FromBody Item Coming Back as Null - c#

I am using JSGrid to allow me to modify data. I am trying to setup the updateItem as follows:
updateItem: function (item) {
return $.ajax({
type: "PUT",
url: "/api/data/" + item.logID,
data: item,
contentType: "application/json;charset=utf-8",
dataType: "json"
});
}
I have a model as follows:
public class LogEntry
{
public string firstName { get; set; }
public string lastName { get; set; }
public string comment { get; set; }
public bool modified { get; set; }
public DateTime inTime { get; set; }
public DateTime outTime { get; set; }
public double totalHrs { get; set; }
public int logID { get; set; }
}
Here is my ApiController Class that contains the Put method:
public class DataController : ApiController
{
public void Put(int id, [FromBody]LogEntry item)
{
if(item != null)
{
//DO STUFF
}
}
}
However no matter what I do the item is always Null. I have tried the following:
Change to [FromBody]JObject item
Change to [FromBody]String item
Change the data: field to Json.Stringify
Change to [FromBody]String to just String
Add and remove context type of application/json;charset=utf-8 to the updateItem ajax call.
I have used Fiddler to see the data sent back. It shows the correct JSON being sent but the Put method doesn't seem to be getting that data.
Any ideas on what might be causing this behavior would be great. I have been researching around but nothing has worked yet.
Resolution Notes
It turned out that both answers from Caz1224 and CodeFuller aided in fixing this. CodeFuller's way of finding the error message lead me to the JSON coming back to the server. It was messed up even though Fiddler said it was correct. I changed my Ajax call to stringify the item. Which then matched my Model exactly.
return $.ajax({
type: "PUT",
url: "/api/data/" + item.logID,
data: JSON.stringify(item),
contentType: "application/json; charset=utf-8",
dataType: "json"

FromBody attribute is not strictly required here because non-simple types are built by the default from the request body.
I don't see any problems with your code so far, it should work for valid request. Seems like the problem is with the request sent and it causes model binding error. To proceed with the analysis check the following:
Check the value of ActionContext.ModelState.IsValid in Put() method. Is it true or false?
If it's false, check collection ActionContext.ModelState.Values in debugger. It should contain model binding errors that will hint you were the problem actually happens.

I had this issue and its painful!!
This is what ended up working for me.
The first part is my javascript (I guess that is how you are making your JSON)
"List" is my array that PERFECTLY matches (Even to the case, it matters) to my C# model.
Javascript Build List
var List = [];
$.each(_questions, function () {
var limitID = this.id.substr(-1);
var Quest = $('#Quest_' + ID).val();
var objectpush = {
LimitID: limitID,
Quest: Quest,
ID: ID
}
List.push(objectpush);
Then in the AJAX call further on I specify data like so:
data: JSON.stringify(List),
And finally this is on my C# API
public JsonResult QueryLimits(int UserID, [FromBody] List<List> List)
Hope this helps get you on the track. Don't just copy the code as I changed the name to List throughout my code and that will cause issues!
Caz

Related

How to pass multiple json array to controller from ajax?

I have two json array. I'm trying to send these json array to my controller. When i want to send one of them, everything is fine but i couldnt't send second one. How can i fix it ?
Post function from view
function HobiIlgiAlanKaydetGuncelle() {
var hobiler = $('#Hobiler').val(); // Json array of object
var ilgiAlanlar = $('#IlgiAlan').val();
$.ajax({
url: "/Kullanici/HobiVeIlgiAlanlariniKaydetGuncelle",
type: "POST",
contentType: 'application/json; charset=UTF-8',
dataType: 'json',
data: {hobiler : hobiler,ilgiAlanlar : ilgiAlanlar},
success: function (response) { }
});
}
Controller
[HttpPost]
public async Task<JsonResult> HobiVeIlgiAlanlariniKaydetGuncelle([FromBody] List<HobilerVM> hobiler, List<IlgiAlanlarVM> ilgiAlanlar)
{
//When I put second parameter, both of them comes with null
}
HobilerVM
public class HobilerVM
{
public int id { get; set; }
public string value { get; set; }
}
IlgiAlanVM
public class IlgiAlanVM
{
public int id { get; set; }
public string value { get; set; }
}
The issue is with the following line:
data: {hobiler : hobiler,ilgiAlanlar : ilgiAlanlar}
This is an object in javascript. The equivalent in c# should be:
public class MyData {
public List<HobilerVM> hobiler;
public List<IlgiAlanlarVM> ilgiAlanlar;
}
And then in your controller:
[HttpPost]
public async Task<JsonResult> HobiVeIlgiAlanlariniKaydetGuncelle([FromBody] MyData data)
{
//When i put second parameter, both of them comes with null
}
For more information, check Why does ASP.NET Web API allow only one parameter for POST method?
Web API doesn’t allow you to pass multiple complex objects in the
method signature of a Web API controller method — you can post only a
single value to a Web API action method. This value in turn can even
be a complex object. It is possible to pass multiple values though on
a POST or a PUT operation by mapping one parameter to the actual
content and the remaining ones via query strings.Reference: How to pass multiple parameters to Web API controller methods and How WebAPI does Parameter Binding
Solution
public class ComplexObject {
property List<HobilerVM> Hobiler { get; set; }
property List<IlgiAlanlarVM> IlgiAlanlar { get; set; }
}
[HttpPost]
public async Task<JsonResult> HobiVeIlgiAlanlariniKaydetGuncelle([FromBody] ComplexObject data)
{
//When i put second parameter, both of them comes with null
}
Happy coding, cheers!
I tried your code and it works fine for me except for some things.
First your second parameter has a different ViewModel on what you have posted on your code:
public class IlgiAlanVM
{
public int id { get; set; }
public string value { get; set; }
}
But on your parameter, you are using a different ViewModel:
([FromBody] List<HobilerVM> hobiler, List<IlgiAlanlarVM> ilgiAlanlar)
As you can see here, IlgiAlanVM is different on List<IlgiAlanlarVM>
Second, I just I used the same code but without the [FromBody]. So that would be:
//I already edited your List of Model here on the second parameter from IlgiAlanVM to IlgiAlanlarVM
[HttpPost]
public async Task<JsonResult> HobiVeIlgiAlanlariniKaydetGuncelle
(List<HobilerVM> hobiler, List<IlgiAlanlarVM> ilgiAlanlar)
Lastly, I just make sure it's an array of objects to make sure it will bind nicely on your list of models:
var hobiler = [{
id: 1,
value: 'My Value'
}];
var ilgiAlanlar = [{
id: 1,
value: 'MyValue'
}];
$.ajax({
url: '#Url.Action("HobiVeIlgiAlanlariniKaydetGuncelle", "Kullanici")',
type: "POST",
contentType: 'application/json; charset=UTF-8',
dataType: 'json',
data: JSON.stringify({ hobiler : hobiler, ilgiAlanlar : ilgiAlanlar }),
success: function (response) { }
});

AWP.Net Web API Post object always empty [duplicate]

I have a Web API service call that updates a user's preferences. Unfortunately when I call this POST method from a jQuery ajax call, the request parameter object's properties are always null (or default values), rather than what is passed in. If I call the same exact method using a REST client (I use Postman), it works beautifully. I cannot figure out what I'm doing wrong with this but am hoping someone has seen this before. It's fairly straightforward...
Here's my request object:
public class PreferenceRequest
{
[Required]
public int UserId;
public bool usePopups;
public bool useTheme;
public int recentCount;
public string[] detailsSections;
}
Here's my controller method in the UserController class:
public HttpResponseMessage Post([FromBody]PreferenceRequest request)
{
if (request.systemsUserId > 0)
{
TheRepository.UpdateUserPreferences(request.UserId, request.usePopups, request.useTheme,
request.recentCount, request.detailsSections);
return Request.CreateResponse(HttpStatusCode.OK, "Preferences Updated");
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, "You must provide User ID");
}
}
Here's my ajax call:
var request = {
UserId: userId,
usePopups: usePopups,
useTheme: useTheme,
recentCount: recentCount,
detailsSections: details
};
$.ajax({
type: "POST",
data: request,
url: "http://localhost:1111/service/User",
success: function (data) {
return callback(data);
},
error: function (error, statusText) {
return callback(error);
}
});
I've tried setting the dataType & contentType to several different things ('json', 'application/json', etc) but the properties of the request object are always defaulted or null. So, for example, if I pass in this object:
var request = {
UserId: 58576,
usePopups: false,
useTheme: true,
recentCount: 10,
detailsSections: ['addresses', 'aliases', 'arrests', 'events', 'classifications', 'custody', 'identifiers', 'phone', 'remarks', 'watches']
}
I can see a fully populated request object with the valid values as listed above. But in the Web API controller, the request is there, but the properties are as follows:
UserId: 0,
usePopups: false,
useTheme: false,
recentCount: 0,
detailsSections: null
FYI - I'm not doing ANY ASP.Net MVC or ASP.NET pages with this project, just using the Web API as a service and making all calls using jQuery $.ajax.
Any idea what I'm doing wrong here? Thanks!
UPDATE: I just want to note that I have many methods in this same Web API project in other controllers that do this exact same thing, and I am calling the exact same way, and they work flawlessly! I have spent the morning comparing the various calls, and there doesn't appear to be any difference in the method or the headers, and yet it just doesn't work on this particular method.
I've also tried switching to a Put method, but I get the exact same results - the request object comes in, but is not populated with the correct values. What's so frustrating is that I have about 20 controller classes in this project, and the Posts work in all of those...
This seems to be a common issue in regards to Asp.Net WebAPI.
Generally the cause of null objects is the deserialization of the json object into the C# object. Unfortunately, it is very difficult to debug - and hence find where your issue is.
I prefer just to send the full json as an object, and then deserialize manually. At least this way you get real errors instead of nulls.
If you change your method signature to accept an object, then use JsonConvert:
public HttpResponseMessage Post(Object model)
{
var jsonString = model.ToString();
PreferenceRequest result = JsonConvert.DeserializeObject<PreferenceRequest>(jsonString);
}
So there are 3 possible issues I'm aware of where the value does not bind:
no public parameterless constructor
properties are not public settable
there's a binding error, which results in a ModelState.Valid == false - typical issues are: non compatible value types (json object to string, non-guid, etc.)
So I'm considering if API calls should have a filter applied that would return an error if the binding results in an error!
Maybe it will help, I was having the same problem.
Everything was working well, and suddently, every properties was defaulted.
After some quick test, I found that it was the [Serializable] that was causing the problem :
public IHttpActionResult Post(MyComplexClass myTaskObject)
{
//MyTaskObject is not null, but every member are (the constructor get called).
}
and here was a snippet of my class :
[Serializable] <-- have to remove that [if it was added for any reason..]
public class MyComplexClass()
{
public MyComplexClass ()
{
..initiate my variables..
}
public string blabla {get;set;}
public int intTest {get;set;
}
I guess problem is that your controller is expecting content type of [FromBody],try changing your controller to
public HttpResponseMessage Post(PreferenceRequest request)
and ajax to
$.ajax({
type: "POST",
data: JSON.stringify(request);,
dataType: 'json',
contentType: "application/json",
url: "http://localhost:1111/service/User",
By the way creating model in javascript may not be best practice.
Using this technique posted by #blorkfish worked great:
public HttpResponseMessage Post(Object model)
{
var jsonString = model.ToString();
PreferenceRequest result = JsonConvert.DeserializeObject<PreferenceRequest>(jsonString);
}
I had a parameter object, which had a couple of native types and a couple more objects as properties. The objects had constructors marked internal and the JsonConvert.DeserializedObject call on the jsonString gave the error:
Unable to find a constructor to use for type ChildObjectB. A class
should either have a default constructor, one constructor with
arguments or a constructor marked with the JsonConstructor attribute.
I changed the constructors to public and it is now populating the parameter object when I replace the Object model parameter with the real object. Thanks!
I know, this is a bit late, but I just ran into the same issue. #blorkfish's answer worked for me as well, but led me to a different solution. One of the parts of my complex object lacked a parameter-less constructor. After adding this constructor, both Put and Post requests began working as expected.
I have also facing this issue and after many hours from debbug and research can notice the issue was not caused by Content-Type or Type $Ajax attributes, the issue was caused by NULL values on my JSON object, is a very rude issue since the POST neither makes but once fix the NULL values the POST was fine and natively cast to my respuestaComparacion class here the code:
JSON
respuestaComparacion: {
anioRegistro: NULL, --> cannot cast to BOOL
claveElector: NULL, --> cannot cast to BOOL
apellidoPaterno: true,
numeroEmisionCredencial: false,
nombre: true,
curp: NULL, --> cannot cast to BOOL
apellidoMaterno: true,
ocr: true
}
Controller
[Route("Similitud")]
[HttpPost]
[AllowAnonymous]
public IHttpActionResult SimilitudResult([FromBody] RespuestaComparacion req)
{
var nombre = req.nombre;
}
Class
public class RespuestaComparacion
{
public bool anioRegistro { get; set; }
public bool claveElector { get; set; }
public bool apellidoPaterno { get; set; }
public bool numeroEmisionCredencial { get; set; }
public bool nombre { get; set; }
public bool curp { get; set; }
public bool apellidoMaterno { get; set; }
public bool ocr { get; set; }
}
Hope this help.
I came across the same issue. The fix needed was to ensure that all serialize-able properties for your JSON to parameter class have get; set; methods explicitly defined. Don't rely on C# auto property syntax! Hope this gets fixed in later versions of asp.net.
A bit late to the party, but I had this same issue and the fix was declaring the contentType in your ajax call:
var settings = {
HelpText: $('#help-text').val(),
BranchId: $("#branch-select").val(),
Department: $('input[name=departmentRadios]:checked').val()
};
$.ajax({
url: 'http://localhost:25131/api/test/updatesettings',
type: 'POST',
data: JSON.stringify(settings),
contentType: "application/json;charset=utf-8",
success: function (data) {
alert('Success');
},
error: function (x, y, z) {
alert(x + '\n' + y + '\n' + z);
}
});
And your API controller can be set up like this:
[System.Web.Http.HttpPost]
public IHttpActionResult UpdateSettings([FromBody()] UserSettings settings)
{
//do stuff with your UserSettings object now
return Ok("Successfully updated settings");
}
In my case problem was solved when i added
get{}set{}
to parameters class definition:
public class PreferenceRequest
{
public int UserId;
public bool usePopups {get; set;}
public bool useTheme {get; set;}
public int recentCount {get; set;}
public string[] detailsSections {get;set;}
}
enstead of:
public class PreferenceRequest
{
[Required]
public int UserId;
public bool usePopups;
public bool useTheme;
public int recentCount;
public string[] detailsSections;
}
As this issue was troubling me for almost an entire working day yesterday, I want to add something that might assist others in the same situation.
I used Xamarin Studio to create my angular and web api project. During debugging the object would come through null sometimes and as a populated object other times. It is only when I started to debug my project in Visual Studio where my object was populated on every post request. This seem to be a problem when debugging in Xamarin Studio.
Please do try debugging in Visual Studio if you are running into this null parameter problem with another IDE.
Today, I've the same problem as yours. When I send POST request from ajax the controller receive empty object with Null and default property values.
The method is:
[HttpPost]
public async Task<IActionResult> SaveDrawing([FromBody]DrawingModel drawing)
{
try
{
await Task.Factory.StartNew(() =>
{
//Logic
});
return Ok();
}
catch(Exception e)
{
return BadRequest();
}
}
My Content-Type was correct and everything else was correct too. After trying many things I found that sending the object like this:
$.ajax({
url: '/DrawingBoard/SaveDrawing',
type: 'POST',
contentType: 'application/json',
data: dataToPost
}).done((response) => { });
Won't work, but sending it like this instead worked:
$.ajax({
url: '/DrawingBoard/SaveDrawing',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(dataToPost)
}).done((response) => { });
Yes, the missing JSON.stringify() caused the whole issue, and no need to put = or anything else as prefix or suffix to JSON.stringify.
After digging a little bit. I found that the format of the request payload completely different between the two requests
This is the request payload with JSON.stringify
And this is the request payload without JSON.stringify
And don't forget, when things get magical and you use Google Chrome to test your web application. Do Empty cache and hard reload from time to time.
I ran into the same issue, the solution for me was to make certain the types of my class attributes matched the json atributes, I mean
Json: "attribute": "true"
Should be treated as string and not as boolean, looks like if you have an issue like this all the attributes underneath the faulty attribute will default to null
I ran into the same problem today as well. After trying all of these, debugging the API from Azure and debugging the Xamarin Android app, it turns out it was a reference update issue. Remember to make sure that your API has the Newtonsoft.JSON NUGET package updated (if you are using that).
My issue was not solved by any of the other answers, so this solution is worth consideration:
I had the following DTO and controller method:
public class ProjectDetailedOverviewDto
{
public int PropertyPlanId { get; set; }
public int ProjectId { get; set; }
public string DetailedOverview { get; set; }
}
public JsonNetResult SaveDetailedOverview(ProjectDetailedOverviewDto detailedOverview) { ... }
Because my DTO had a property with the same name as the parameter (detailedOverview), the deserialiser got confused and was trying to populate the parameter with the string rather than the entire complex object.
The solution was to change the name of the controller method parameter to 'overview' so that the deserialiser knew I wasn't trying to access the property.
I face this problem this fix it to me
use attribute [JsonProperty("property name as in json request")]
in your model by nuget package newton
if you serializeobject call PostAsync only
like that
var json = JsonConvert.SerializeObject(yourobject);
var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
var response = await client.PostAsync ("apiURL", stringContent);
if not work remove [from body] from your api
HttpGet
public object Get([FromBody]object requestModel)
{
var jsonstring = JsonConvert.SerializeObject(requestModel);
RequestModel model = JsonConvert.DeserializeObject<RequestModel>(jsonstring);
}
public class CompanyRequestFilterData
{
public string companyName { get; set; }
public string addressPostTown { get; set; }
public string businessType { get; set; }
public string addressPostCode{ get; set; }
public bool companyNameEndWith{ get; set; }
public bool companyNameStartWith{ get; set; }
public string companyNumber{ get; set; }
public string companyStatus{ get; set; }
public string companyType{ get; set; }
public string countryOfOrigin{ get; set; }
public DateTime? endDate{ get; set; }
public DateTime? startDate { get; set; }
}
webapi controller
[HttpGet("[action]"),HttpPost("[action]")]
public async Task<IEnumerable<CompanyStatusVm>> GetCompanyRequestedData(CompanyRequestFilterData filter)
{}
jsvascript/typescript
export async function GetCompanyRequesteddata(config, payload, callback, errorcallback) {
await axios({
method: 'post',
url: hostV1 + 'companydata/GetCompanyRequestedData',
data: JSON.stringify(payload),
headers: {
'secret-key': 'mysecretkey',
'Content-Type': 'application/json'
}
})
.then(res => {
if (callback !== null) {
callback(res)
}
}).catch(err => {
if (errorcallback !== null) {
errorcallback(err);
}
})
}
this is the working one c# core 3.1
my case it was bool datatype while i have changed string to bool [companyNameEndWith] and [companyNameStartWith] it did work. so please check the datatypes.

AJAX POST Request Not Passing Data to Controller Method in ASP.NET Core 2.2

Before I begin, I'd like to say - I realize that this question is very similar to many others that have been posted and answered on this site. I have read through and tried as many solutions as I could find that was related to my issue, and none have worked thus far.
I'm attempting to pass data from my web page to a controller method. The web page is very simple and only needs to capture information input by the user and send it off. I'm using Telerik's Kendo Grid to bind to and organize my data. No matter what I try, though, my AJAX post request never passes parameters forward correctly. When using my browser's debugger, I can see that the parameters being passed into the AJAX request are valid, but by the time they hit my breakpoint in the controller method, they are all either null or default.
Function Containing AJAX Request
function saveShiftDataToServer() {
var grid = $("#myGrid").data("kendoGrid");
var dataSource = grid.dataSource;
var allData = dataSource.data();
var comments = '#Model.Comments';
var loadInfoCorrect = '#Model.LoadInfoCorrect';
$.ajax({
type: "POST",
url: '/Home/SaveData',
data: JSON.stringify({ accessorials: allData, comments: comments, loadInfoCorrect: loadInfoCorrect }),
contentType: "application/json; charset=utf-8",
datatype: "json"
})
}
Controller Method
[AcceptVerbs("Post")]
public ActionResult SaveData(Accessorial[] accessorials, string comments, bool loadInfoCorrect)
{
// Code removed for brevity
}
My Kendo Grid is typed as Accessorial (the first controller method parameter type), so my assumption is that retrieving a collection of all present rows should return an array of that model. Even so, "comments" is a string, but is only ever passed to the controller method as null.
I'm new to ASP.NET Core and Kendo, so I'm sure there is something obvious that I'm missing. Any help would be appreciated!
I appreciate all of the responses! I was able to finally see valid data in my controller by changing the AJAX data type to "text" and simply passing the JSON directly for deserialization server-side. For some reason this is the only way that I've been able to make this work thus far.
AJAX POST Call
function saveShiftDataToServer() {
var grid = $("#accessorialGrid").data("kendoGrid");
var dataSource = grid.dataSource;
var allData = dataSource.data();
var shiftOverview = {
ShiftId: 0,
UserName: "test",
ShiftDate: null,
LoadList: null,
AccessorialList: allData,
LoadInfoCorrect: true,
Comments: ""
};
var jsonData = JSON.stringify(shiftOverview);
$.ajax({
type: "POST",
url: '/Home/SaveData',
data: { json: jsonData },
datatype: "text",
success: function (response) {
alert("111");
}
})
}
Controller Method
[AcceptVerbs("Post")]
public ActionResult SaveData(string json)
{
JsonConvert.DeserializeObject<ShiftOverview>(json); // This produces an object with valid data!
}
You could pass all your data in a ViewModel and get access to it using [FromBody] on action
public class ViewModel
{
public List<Accessorial> Accessorials{ get; set; }
public string Comments { get; set; }
public bool LoadInfoCorrect { get; set; }
}
Ajax:
var model = {};//pass all you data to an object
model.Accessorials = allData ;
model.comments = comments ;
model.loadInfoCorrect = loadInfoCorrect;
var items = JSON.stringify(model);
$.ajax({
url: '/GetAllCustDetails/SaveData',
type: "POST",
data: items,
contentType: 'application/json; charset=utf-8',
//dataType: "json",
success: function (response) {
alert("111");
}
});
Controller:
[HttpPost]
public ActionResult SaveData([FromBody]ViewModel model)
You are passing JSON object which corresponds to C# one like this:
public class Model {
public Accessorial[] Accessorials { get; set; }
public string Comments { get; set; }
public bool loadInfoCorrect { get; set; }
}
Try to declare such class above and adjust your action method this way:
public ActionResult SaveData(Model model)
{
// Code removed for brevity
}
If won't help - make model parameter object and check in debug mode what you are getting from AJAX call.
You juste have to use the [FromBody] attribute in your action method, like this :
[HttpPost]
public ActionResult SaveData([FromBody]Model model)
{
// Code removed for brevity
}

asp.net Web-Api JSON string deserialization

I followed this tutorial to create a Restful web-api service.
Everything seemed to work well, I can get all the bookings in JSON format by requesting them from the correct url.
My issue is with the http POST.
My Javascript is:
var url = 'http://localhost:9077/api/bookings';
....
var newEvent = [];
newEvent.EventDateTime = // (now);
newEvent.Name = "MyFirstBooking";
function btnSubmit_Click()
{
alert("Submit clicked: " + newEvent.Name + "\n" + newEvent.EventDateTime);
$.ajax({
type: "POST",
url: url,
data: JSON.stringify( { Bookings: newEvent }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) { alert(data); }
});
}
The alert displays the correct date and also the correct name.
When I click Submit and check fiddler it looks like the JSON is correctly formatted:
{"Bookings":[{"Name":"MyFirstBooking","EventDateTime":"2014-04-14T13:45:00.000Z"}]}
My View is Bookings.cs :
public class Bookings
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime BookingDateTime { get; set; }
public DateTime EventDateTime { get; set; }
public int Duration { get; set; }
public int UserID { get; set; }
}
In my BookingsController I have:
public HttpResponseMessage PostBooking(Bookings item)
{
// Implementation
}
However when I put a breakpoint after PostBooking, item.EventDateTime is {01/01/0001 00:00:00} and Name is null.
It seems like the JSON is not being deserialised correctly...? I'm not sure where this happens as I can't find it mentioned anywhere...
Thanks.
ahhh dates in javascript. Aren't they fun? You are more than likely going to have to do a converstion either in javascript or take a look at this stack overflow question to implement a custom date handler in your api:
ASP.NET Web API Date format in JSON does not serialise successfully
EDIT: Ahh i also noticed that your JSON object is an array. You will need to change your signature to take an array:
public HttpResponseMessage PostBooking(IEnumerable<Bookings> items)
{
// Implementation
}
EDIT AGAIN:
on second thought, I dont think your event needs to be an array. I think you want to do this:
var newEvent ={};
this will intialize newEvent as an object instead of a an array. then you can leave your signature as is. You might need to change your param name like tomasofen mentioned in his answer as well.
EDIT AGAIN:
further thought: you dont need to root the object with {"Bookings": newEvent } just do this instead:
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(newEvent),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) { alert(data); }
});
you are setting the contentType to json. This tells your web app that the content should be json, which in turn will be handled and converted by the server. By stringifying it, you are turning the content into a string and therefore changing the contentType.
Try using the same name for the variable in the server method than the name of the Json parameter:
For server side:
public HttpResponseMessage PostBooking(Bookings item)
{
// Implementation
}
For client side (just change "item" as name of the param):
{"item":[{"Name":"MyFirstBooking","EventDateTime":"2014-04-14T13:45:00.000Z"}]}
I had issues with this, and perhaps this is your case. Tell us if it works or not to try other things.
Check also that the object Bookings in the server has the members Name and EventDateTime writen in the same way.

Json array object is always empty when posted to mvc actionresult

My raw json string passed to the MVC ActionResult Controller via AJAX post
{"ID":0,"RoutingRuleID":24,"ConditionalType":0,"Field":"Channel","ConditionalOperator":"5","Values":[1,9],"ValueString":""}
But what ends up happening is that once the json objects gets to the MVC controller it loses the values in the Associated Array "Values". The other properties are set correctly.
My model Class in C# is as follows:
public class RoutingConditional
{
public int ID { get; set; }
public int ParentID { get; set; }
public string ConditionalType { get; set; }
public string Field { get; set; }
public string ConditionalOperator { get; set; }
public List<string> Values { get; set; }
public string ValueString{get;set;}
public RoutingConditional()
{
//this.Values = new List<string>(); //I tried to initialize it too did not work
}
}
My MVC Controller
[HttpPost]
public ActionResult EditConditional(RoutingConditional rcview)
{
//rcview.Values = null
}
My Javascript
$.ajax({
url: actionURL,
type: "post",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(myModel.RoutingConditional),
........standard success and error
});
Why is it being passed in as null for the array(List)?
This is a weird one, not sure I can fully explain (have an idea) but here's what I did.
Stripped out all your json parameters in the payload except the "Values":[1,9] and it worked just fine.
So started adding back each json parameter starting at the end (luckily). When I re-added "ValueString":"" it crapped out again.
So added a few more json params to see if it was an ordering issue (e.g., nothing can go after the array). That wasn't the case.
So started renaming stuff and when I renamed "ValueString":"" to something like "TmpValueString":"" it worked again.
Here's my best guess. The word ValueString has pieces of the name that match the first characters another property. In this instance, "values-tring" matches with "values" (array name) thereby throwing the MVC binder off when it goes to match against your object model. I'm not 100% on this, but that's what it seems.
So your solution is to rename one of your props so that its name does not make up the first characters of another prop.
Also, wanted to mention ConditionalOperator and ConditionalType names to counter any arguments. These names are unique in that they are not subsets of each other, but merely contain like characters. Whereas Values is a subset of Valuestring thus causing, what I think, is binding confusion.
Try setting the `traditional' option
$.ajax({
url: actionURL,
type: "post",
dataType: 'json',
traditional: true,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(myModel.RoutingConditional),
........standard success and error
});

Categories

Resources