De-serializing object in MVC4 action results in null values - c#

I am using jQuery 1.9.1 and MVC 4.
I have the following javascript:
$.ajax({
url: '/Home/doSomething',
type: 'POST',
data: JSON.stringify({ devices: [{ Id: 123, Name: "something", MapName: "map" },{ Id: 321, Name: "a name", MapName: "another map" }] }),
dataType: 'json',
contentType: 'application/json'
}
And the following c# in my HomeController:
[HttpPost]
public string doSomething( Device[ ] devices )
{
//stuff consuming that array
}
The Device class is defined like this:
[Serializable]
public class Device
{
public long Id;
public string Name;
public string MapName;
}
According to the debugger, the devices array is a 2-element array with all properties of each Device element being null.
According to chrome, the post data looks like this:
{
"devices": [
{
"Id": 123,
"Name": "something",
"MapName": "map"
},
{
"Id": 321,
"Name": "a name",
"MapName": "another map"
}
]
}
What is wrong here that is making MVC swear up and down that those objects are null, yet still giving me an appropriate-length array of them?
I have tried posting the array directly, without calling JSON.stringify on it.
I have tried posting the array inside an object as a property called "devices", again without strigifying it.
I have tried posting the array inside an object as a property called "devices", while only stringifying the array itself.
All of these result in bad behavior of one form or another. Either chrome does not post the appropriate data in the first place, or MVC does not de-serialize it.
I have scoured the web and can't seem to find any examples of why this should be broken.
Edit 2013-02-21 13:12 UTC-5:
I have also tried this without using JSON and just letting jQuery post it as form data.
Here is the code for that:
var postData = { devices: [{ Id: 123, Name: "something", MapName: "map" }, { Id: 321, Name: "a name", MapName: "another map" }] };
$.ajax({
url: '/Home/doSomething',
type: 'POST',
data: postData
});
And the C# is still the same as above.
The behavior is still the same as when it was JSON, though.
MVC sees an array of 2 elements, but all values of the objects in that array are default (0 for the integer and null for the strings).

Here's what finally worked...
First, I changed the javascript to make the object with a property called "devices" that contains the stringified array:
var postData = { devices: JSON.stringify([{ Id: 123, Name: "something", MapName: "map" }, { Id: 321, Name: "a name", MapName: "another map" }]) };
$.ajax({
url: '/Home/doSomething',
type: 'POST',
dataType: 'json',
data: postData
}
Then I made the controller action take a single string called "devices" and de-serialized it manually using JSON.Net:
[HttpPost]
public string MakeMmLinks( string devices )
{
List<Device> devicesList = JsonConvert.DeserializeObject<List<Device>>( devices );
...
}
This worked fine, but what bothers me is that object de-serialization is supposed to be something that MVC handles natively.
If anyone has any insight on what happened here or what I did wrong, I'd love to hear it.

In cases like this I've found tradition: true is very important. Not sure you need stringify
dataType: 'json',
traditional: true

You are posting an object with a property that contains an array of 2 devices.
If you want to just post the device array, than try the following.
var devices = [{ Id: 123, Name: "something", MapName: "map" }, { Id: 321, Name: "a name", MapName: "another map" }];
$.ajax({
url: '/Home/doSomething',
type: 'POST',
data: JSON.stringify(devices),
dataType: 'json',
contentType: 'application/json'
});

Related

C# and Ajax - Posting 2 values from JS to C#

I'm using ajax to send an int64 and a string from a month selector to my server-side, but my variable is always null or 0.
JS:
function deleteConta(id) {
var data = $("#monthSelector").val();
var params = {
id: id,
dataAtual: data
};
$.ajax({
type: "POST",
url: '/Contas/ContaView?handler=Delete',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(params),
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (partialReturn) {
$("#partial").html(partialReturn);
}
});
}
C#:
public PartialViewResult OnPostDelete([FromBody] long id, string dataAtual)
{
contaDTO.Remove(id, contaDTO.Database, contaDTO.ContaCollection);
dataCorrente = DateTime.ParseExact(dataAtual, "yyyy-MM", null).AddMonths(1);
contas = BuscarContasUsuarioMes(User.Identity.Name, dataCorrente);
return Partial("_PartialContas", contas);
}
I already checked with debugger and my variables are ok and filled with value expected (One test was like {id: 50, dataAtual: '2023-01'}
Checked a lot of forums, but Couldn't figure out how to make this thing work.
By declaring the number parameter with [FromBody] you tell ASP.NET Core to use the input formatter to bind the provided JSON (or XML) to a model. So your test should work, if you provide a simple model class.
Have you tried to remove it and sending value to the action?
—- UPDATE ——
Try this
function deleteConta(id) {
var data = $("#monthSelector").val();
$.ajax({
type: "POST",
url: '/Contas/ContaView?handler=Delete',
data: { id: id, dataAtual: data },
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (partialReturn) {
$("#partial").html(partialReturn);
}
});
}

Receving null value in controller action via AJAX

Salaamun Alekum
I am getting null in controller action via an AJAX request:
var ProjectPermission = [{
"CreatedBy": "Akshay"
},{
"CreatedBy": "Kumar"
},{
"CreatedBy": "ETC"
}]
$.ajax({
url: '/api/Projects/AssignProjectPermissions',
type: 'POST',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify({
ProjectPermission: ProjectPermission
}),
success: function (data) {
alert(data);
},
// processData: false //Doesn't help
});
My C# controller:
[System.Web.Http.HttpPost, System.Web.Http.HttpGet]
public string AssignProjectPermissions(ProjectPermission[] ProjectPermission)
{
I am getting null in ProjectPermission. I already tried other answers but none of them worked for me. These were the posts I checked:
How to get Ajax posted Array in my C# controller?
Ajax post to ASP.net MVC controller - object properties are null
Thank You
You should not be using GET and POST on the same method first of all, just use POST in this case. That aside you do not need the property name. You are putting your array inside of an object. Your method is expecting an array.
var ProjectPermission = [{ CreatedBy: "Akshay" },
{ CreatedBy: "Kumar" },
{ CreatedBy: "ETC" }]
$.ajax({
url: '/api/Projects/AssignProjectPermissions'
, type: 'POST'
, contentType: 'application/json'
, dataType: 'json'
, data: JSON.stringify(ProjectPermission) //<------------issue here
, success: function (data)
{ alert(data); }
//, processData: false
});

how to pass array data to the javascript code from asp.net page?

i have a chart template with javascript code and this is the part of it:
// Toggling Series
var datasets = {
"Iran": {
label: "IR",
data: [
[1988, 483994],
[1989, 479060],
[1990, 457648],
[1991, 401949],
[1992, 424705],
[1993, 402375],
[1994, 377867],
[1995, 357382],
[1996, 337946],
[1997, 336185],
[1998, 328611],
[1999, 329421],
[2000, 342172],
[2001, 344932],
[2002, 387303],
[2003, 440813],
[2004, 480451],
[2005, 504638],
[2006, 528692]
]
},
"russia": {
label: "Russia",
data: [
[1988, 218000],
[1989, 203000],
[1990, 171000],
[1992, 42500],
[1993, 37600],
[1994, 36600],
[1995, 21700],
[1996, 19200],
[1997, 21300],
[1998, 13600],
[1999, 14000],
[2000, 19100],
[2001, 21300],
[2002, 23600],
[2003, 25100],
[2004, 26100],
[2005, 31100],
[2006, 34700]
]
}
};
now i want pass data from array variable to java script for replace with this data on asp.net page load event.
how to pass array list to this ? can write a sample code ?
Note: my data is big and this java script data is sample only and is better to pass array or variable!
You can't directly pass a variable from your .NET application to the client-side JavaScript. Instead you need to either include the full list data in the script source (as you've done partially above) or use AJAX or similar to query the data from the server.
You can shorten the code using something like JSON.net to serialize the object you're trying to embed:
var datasets = <%= NewtonSoft.Json.JsonConvert.SerializeObject(ViewBag.datasets) %>;
Or you can write the code to generate the layout yourself... personally I prefer the simpler JsonConvert option.
Something like this, (I haven't tested it)
Create a method in you .cs file :
[WebMethod]
public static string GetData()
{
var datasets = {
"Iran": {
label: "IR",
data: [
[1988, 483994],
[1989, 479060],
[1990, 457648],
[1991, 401949],
[1992, 424705],
[1993, 402375],
[1994, 377867],
[1995, 357382],
[1996, 337946],
[1997, 336185],
[1998, 328611],
[1999, 329421],
[2000, 342172],
[2001, 344932],
[2002, 387303],
[2003, 440813],
[2004, 480451],
[2005, 504638],
[2006, 528692]
]
},
"russia": {
label: "Russia",
data: [
[1988, 218000],
[1989, 203000],
[1990, 171000],
[1992, 42500],
[1993, 37600],
[1994, 36600],
[1995, 21700],
[1996, 19200],
[1997, 21300],
[1998, 13600],
[1999, 14000],
[2000, 19100],
[2001, 21300],
[2002, 23600],
[2003, 25100],
[2004, 26100],
[2005, 31100],
[2006, 34700]
]
}
};
return dataset;
}
Then in you jquery load/document ready function:
$.ajax({
type: "POST",
url: "PageName.aspx/GetData",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
$("domelement").html(data);
}
});

Read and Parse JSON data from POST request in C#

I'm doing a POST request via JQuery's Ajax, with the type of data defined as json, containing the values to be posted to server, something like Username: "Ali".
What I need to do in a Handler, is to read the values, deserialize them to an object named User.
String data = new System.IO.StreamReader(context.Request.InputStream).ReadToEnd();
User user = JsonConvert.DeserializeObject<User>(data);
While debugging, the value of data is the following:
Username=Ali&Age=2....
Now I'm sure this isn't JSON, so the next line would certainly produce an error:
"Unexpected character encountered while parsing value: U. Path '', line 0, position 0."
What is the proper way to read JSON data from POST request?
Client Side
$.ajax({
type: 'POST',
url: "http://localhost:38504/DeviceService.ashx",
dataType: 'json',
data: {
Username: 'Ali',
Age: 2,
Email: 'test'
},
success: function (data) {
},
error: function (error) {
}
});
Convert your object to json string:
$.ajax({
type: 'POST',
url: "http://localhost:38504/DeviceService.ashx",
dataType: 'json',
data: JSON.stringify({
Username: 'Ali',
Age: 2,
Email: 'test'
}),
success: function (data) {
},
error: function (error) {
}
});
I am not sure why your datastring is encoded like an url (as it seems).
But this might solve the problem (altough i am not sure)
String data = new System.IO.StreamReader(context.Request.InputStream).ReadToEnd();
String fixedData = HttpServerUtility.UrlDecode(data);
User user = JsonConvert.DeserializeObject<User>(fixedData);
Use This In c# file... Will give you result you require...
string username=Request.Form["Username"].ToString();
Similarly For others...
I hope this will help you
Another Answer Or you can send data like this
$.ajax({
url: '../Ajax/Ajax_MasterManagement_Girdle.aspx',
data: "Age=5&id=2"
type: 'POST',
success: function (data) {
}
});
ANd get the answer like this in c#
string Age=Request.Form["Age"].ToString();

Model binding is binding my json array, but not the values

I am using ASP.NET MVC 3 and I'm trying to model bind a simple json array to a List<JsonPositions>. JsonPositions is a custom object with the same properties as the json objects in the array.
Here is what my array looks like on the client:
var widgetPositions = [
{ col: 5, row: 1, id: 2 },
{ col: 4, row: 5: id: 40 }
];
$.ajax({
url: 'the url',
data: { positions: widgetPositions },
success: function () {
alert('Save successful.');
},
error: function () {
alert('An error occurred while trying to update the widget positions.');
}
});
This code appears to be working correctly when the request is examined in Chrome.
In the controller we have the following action method:
public void UpdatePositions(List<JsonPosition> positions)
{
// debugging here
}
When I examine the widgetPositions list it does have two items just like the json array, but the objects' properties do not match the values from the objects on the client. Here is what the object JsonPosition looks like:
public class JsonPosition
{
public int id { get; set; }
public int col { get; set; }
public int row { get; set; }
}
Thanks for any help you can offer :)
I think you may need to add the content-type:
$.ajax({
url: 'the url',
data: JSON.stringify({ positions: widgetPositions }),
contentType: 'application/json',
success: function () {
alert('Save successful.');
},
error: function () {
alert('An error occurred while trying to update the widget positions.');
}
});
Also you're not specifying a request type, so it will do a GET by default, do you mean to be doing a POST? That would make it
$.ajax({
url: 'the url',
type: 'POST',
data: JSON.stringify({ positions: widgetPositions }),
contentType: 'application/json',
success: function () {
alert('Save successful.');
},
error: function () {
alert('An error occurred while trying to update the widget positions.');
}
});
You could send them as a JSON object:
var widgetPositions = [
{ col: 5, row: 1, id: 2 },
{ col: 4, row: 5: id: 40 }
];
$.ajax({
url: 'the url',
data: JSON.stringify({ positions: widgetPositions }),
contentType: 'application/json',
success: function () {
alert('Save successful.');
},
error: function () {
alert('An error occurred while trying to update the widget positions.');
}
});
Things to notice that you hadn't in your code and which will make it work:
contentType: 'application/json', - set the proper request content type header
data: JSON.stringify({ positions: widgetPositions }) - send a JSON request
Now you will happily get all you need here:
public void UpdatePositions(List<JsonPosition> positions)
{
// debugging here
}
Remark: The JSON.stringify method is natively defined in all modern browsers (even in IE8, even if this is far from being a modern browser). But if you need to support some prehistoric browsers you could include the json2.js script to your page which will check whether the browser natively supports this method and if not provide an implementation.

Categories

Resources