C# pares json string to "\"String\"" - c#

We have 2 mvc applications
When we send JSON data from the view to the controller with an ajax call.
(the code from both the controller and view are 100% identical)
var JsonData = {"Name" : "Jon Jonssen", "Foo": "test", "Date": new Date(2010,02,02)}
$.ajax({
type: 'POST',
url: "#Url.Action("TestJson")",
data: JsonData,
success: function(data) { alert('data: ' + JSON.stringify(data)); },
contentType: "application/json",
dataType: 'json'
});
Model:
public string Name { get; set; }
public string Foo { get; set; }
public DateTime Date { get; set; }
Controller:
public ActionResult TestJson(JsonModel JsonModel)
Application 1 gets the object as following:
Name = "Jan Janssen"
Foo = "test"
Date = 2-2-2010 00:00:00
Application 2 gets the following:
Name = "\"Jan Janssen\""
Foo = "\"test\""
Date = 1-1-0001 00:00:00
We can't seem to find any difference. Any help would be nice.

Replace:
data: JsonData
with:
data: JSON.stringify(JsonData)
The reason you need to do this is because you have specified contentType: "application/json" in your HTTP request so you must respect this settings and send JSON.
Also if you properly set the response Content-Type header to application/json (which happens under the covers if you return a JsonResult from your controller action) you don't need to specify explicitly the dataType: 'json'. jQuery will automatically infer this from the header.

Related

Retrieve data (associative array) sent to controller's action with AJAX

I try to POST a form in AJAX and one of the parameter is an associative array.
I can check in Console that the request is okay and parameters are correctly sent.
This is the AJAX call
var fieldsEdited = [{"Key":1,"Values":["value1"]},{"Key":2,"Values":["value2"]}, ...]
$.ajax({
url: "/url"
type: 'POST',
data: { fieldsEdited: JSON.stringify(fieldsEdited) },
dataType: 'json',
traditional: true,
success: function (data, textStatus, jqXHR) { }
});
But I can't "map" these parameters in the action of the controller
I have tried to get them like that
[HttpPost]
public ActionResult Method(List<DictionaryInfos> fieldsEdited)
with
[Serializable]
public class DictionaryInfos
{
public int Key { get; set; }
public List<String> Values { get; set; }
}
but the result is always an empty array, I can't retrieve correct data.
What is wrong ?
There is at least one problem with your code: dataType is not the type of what you're sending to the server, but what you're expecting back from the server.
You must specify contentType to let the server know what kind of data you're sending to it:
contentType: "application/json; charset=utf-8"
Besides, it's possible that you need to change
data: { fieldsEdited: JSON.stringify(fieldsEdited) },
to
data: JSON.stringify(fieldsEdited),
or even simply to
data: fieldsEdited

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 object binding in MVC

I seem to be having a problem passing a javascript object, which contains an array, to my MVC controller. I have an object which contains two strings, and a string array. The two strings bind correctly, but as soon as I add an array to the obect I get the following error:
Collection is read-only.
Here is my JS + Ajax code:
$('.submit').on('click', function() {
var viewModel = {
FName: "John",
LName: "Doe",
DaysOfTheWeek: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
};
console.log(viewModel);
$.ajax({
url: "/Home/JsonMethod",
type: "POST",
data: JSON.stringify(viewModel),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
console.log(data);
}
});
});
Here is my MVC controller:
public JsonResult JsonMethod(Person person)
{
return Json(person, JsonRequestBehavior.AllowGet);
}
Here is the Person class:
public class Person
{
public string FName { get; set; }
public string LName { get; set; }
public string[] DaysOfTheWeek { get; set; }
public Person()
{
DaysOfTheWeek = new string[7];
}
}
I've had a look online, but I can't find anything that deals with the following issue. Any help with this matter would be great.
Problem might be because you've initialized array in your Person's constructor and when deserializer sees that there are already collection - it tries to add to it instead of create new one. Try to either remove initialization from constructor or change type to List.
List binding is simple and straightforward, but there are valid times (or uncontrollable times) to work with arrays as parameters on controller actions.
You can modify your $.ajax call to set the traditional parameter to true, which works with the expectations of the default model binder in the MVC Framework.
$.ajax({
url: "/Home/JsonMethod",
traditional: true,
type: "POST",
data: JSON.stringify(viewModel),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
console.log(data);
}
});
More details and examples here:
http://theycallmemrjames.blogspot.ca/2010/05/aspnet-mvc-and-jquery-part-4-advanced.html
Cheers.
You need to change the property from:
public string[] DaysOfTheWeek { get; set; }
To:
public List<string> DaysOfTheWeek { get; set; }

HTTP POST request to C# Controller

I'm trying to make HTTP POST request to my C# controller, but I need to send in data an array, so I tried with JSON.stringify but when I start debugging, the input parameter in my controller is NULL?
I'm receiving a list from external API for weather forecast, so I need to create for each item in list new variable, that has some fields like : max and min temperature, description, humidity, pressure etc, and then of course fill these fields with data and add that variable to my array. Then I need to pass this array to my controller so I could store it in my database...
What type should I put in my controller so it would not be NULL? I'm totally new here so please help, any help is really more then welcome!
Below is code I have just to try :
var myData = { id:100, description:"some text"};
var myDataArray= new Array();
myDataArray.push(myData);
$.ajax({
dataType: "json",
type: "POST",
url: "/Weather1/Weather_post",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(myDataArray),
success: function (data) {
console.log(("OK"));
},
error: function (error)
{ console.log("NOT OK"); }
})
Controller:
[HttpPost]
public JsonResult Weather_post(String MyModuleList)
Model binding has no idea what "MyModuleList" is. You can use a strongly typed model here and MVC will bind the JSON to it.
Consider JSON:
var data = {
moduleList: [
{ id:100, description:"some text"}
];
};
and models:
public class ModuleListModel
{
public List<ModuleModel> ModuleList { get; set; }
}
public class ModuleModel
{
public int Id { get; set; }
public string Description { get; set; }
}
and action:
[HttpPost]
public JsonResult Weather_post(ModuleListModel model)
{
...
}
Combine that with #Timothy Shields' answer:
You're missing processData: false in your ajax call. Without that,
ajax is going to try to pack the data into the URL query string. (See
here: http://api.jquery.com/jQuery.ajax/)
and you should be good.
You're missing processData: false in your ajax call. Without that, ajax is going to try to pack the data into the URL query string. (See here: http://api.jquery.com/jQuery.ajax/)
If data is { 'animal': 'elephant', 'count': 5 } and processData is true (the default), ajax will do the POST to the URL /Weather1/Weather_post?animal=elephant&count=5 with an empty HTTP request body. This is why you want processData: false.
Try as follows:
var myData = { id:100, description:"some text"};
var myDataArray= new Array();
myDataArray.push(myData);
var param = JSON.stringify(myDataArray);
$.ajax({
dataType: "json",
type: "POST",
url: "/Weather1/Weather_post",
contentType: "application/json; charset=utf-8",
data: {'MyModuleList': param },
success: function (data) {
console.log(("OK"));
},
error: function (error)
{ console.log("NOT OK"); }
})
You may need to pass the parameter name with the data. Something like:
data: {'MyModuleList': JSON.stringify(myDataArray)},
See if this works for you.

Why does the modelbinder instantiate empty objects for my list in ASP.NET MVC4?

I have a json object like this:
var itemData = {
"translations":[
{
"value":"Byron",
"languageId":1
},
{
"value":"hgfdfghds",
"languageId":3
}
],
"itemId":204,
"itemCategoryId":44
};
And I POST it using jQuery like this:
$.ajax({
url: "items/update",
dataType: "json",
type: "POST",
data: itemData,
});
When the call arrives at my ASP.NET MVC4 controller action, the non-list properties are assigned. However, the translations array only has two empty objects (instantiated, but with null/default property values). Here is my controller action method and my models:
public JsonResult Update(UpdateItemModel model)
{
if(model.Translations[0].Value!="Byron")
{
throw new Exception("That translation's value should have been populated with 'Byron'.");
}
return Json("ok");
}
public class UpdateItemModel
{
public List<TranslationModel> Translations { get; set; }
public int ItemId { get; set; }
public int ItemCategoryId { get; set; }
}
public class TranslationModel
{
public string Value { get; set; }
public int LanguageId { get; set; }
}
If I look at Request.Form in the immediate window, I can see that the translations "array" is encoded for some reason (maybe that's correct, not sure). If I try Request.Form["translations"] I get null. Here's an example of the raw form data that I'm seeing:
{translations%5b0%5d%5bvalue%5d=Byron&translations%5b0%5d%5blanguageId%5d=1&translations%5b1%5d%5bvalue%5d=hgfdfghds&translations%5b1%5d%5blanguageId%5d=3&itemId=204&itemCategoryId=44}
Not sure if my problem has anything to do with the "encoding" of the json at the beginning of that string. I looked at it in Fiddler and saw the same thing, so I can't blame ASP.NET for tampering.
What could be the problem here?
You should specify the content type (json) and stringify it using JSON.stringify
$.ajax({
url: "items/update",
dataType: "json",
contentType: "application/json; charset=utf-8;",
type: "POST",
data: itemData,
data: JSON.stringify(itemData),
});
Another thing to do is use add a JsonValueProviderFactory:
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
in Application_Start method in Global.asax
This article might help you.
When you pass data for Ajax call is good to specify the content and stringfy the data:
$.ajax({
/*More stuff*/
data: JSON.stringify(itemData),
contentType: 'application/json',
dataType: "json",
type: "POST"
});
Then the value provider and the default ModelBinder will do the job.
I can see the json object properties are not matching .net properties, In json you have "value" in .net "Value" case is different. Try making the case to march the .net model

Categories

Resources