json object binding in MVC - c#

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; }

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

AJAX Post Multiple Data to ASP.Net MVC

I am facing problem while posting multiple objects via ajax jquery to MVC 4 controller. It has been weeks but I can't seem to find a solution.
I tried several approaches, sometimes the filterModel object is null and sometimes string parameters are null (doesn't matter even if I stringify of if I specify contentType or not)
What I want?
I want to pass three objects: 1. filterModel 2.testparamA 3.testparamB
What should I do to pass all three objects to MVC controller? What do I need to write in data: so I get all 3 object values?
The simplest Controller
[HttpPost]
public JsonResult Test(string testparamA, string testparamB, FilterModel filter)
{
using (RBSystemEntities repository = new RBSystemEntities())
{
return Json(new {
DataList = repository.Items.Select(x => new {x.PKID, x.ItemName}).ToList(),
Result = "OK"
});
}
}
The simplest View
var filterModel = #Html.Raw(Json.Encode(new FilterModel("ItemName", "Pepperoni Pizza")))
//filterModel = JSON.stringify(filterModel);
function testme() {
// post the javascript variable back to the controller
$.ajax({
url: '/Menu/Test',
type: 'POST',
//contentType: 'application/json; charset=utf-8',
data: {
filter: filterModel,
testparamA: 'A value',
testparamB: 'B value'
}, // with this approach I get filterModel null in the controller however testparamA and testparamB has values
data: filterModel, // with this approach I get values for filterModel but I can't pass testparamA and testparamB
success: function (result) {
// TODO: do something with the results
alert('success');
}
});
}
testme();
The simplest FilterModel class
public class FilterModel
{
public FilterModel() { }
public FilterModel(string filtercolumn, string filtervalue)
{
this.FilterColumn = filtercolumn;
this.FilterValue = filtervalue;
this.FilterColumnCriteria = "=";
}
public string FilterColumn { get; set; }
public string FilterValue { get; set; }
public string FilterColumnCriteria { get; set; }
}
Hope you don't mind me posting my comment (which was helpful) as an answer...
If you use stringify as follows it should work...
JSON.stringify({ fm: filterModel, ta: testparamA, tb: testparamA })
#PaulZahra guided me to the right direction.
Below changes fixed my problem:
contentType: 'application/json; charset=utf-8', // uncomment this
data: JSON.stringify({ filter: filterModel, testparamA: 'A value', testparamB: 'B value' }), //stringify whole thing and not just c# class

C# pass parameter from ajax call to class

I have an ajax call like so:
var is_where = true;
$.get("/api/airport/getListItems", { where: is_where}, function (data) {
});
And I am trying to pass it here:
public class AirportClass{
public List<AirportClass> getListItems(string where = null){
}
}
and I put a break point on my public List and where is still equal null when I am expecting true, am i passing this in wrong? if so, how would I fix it?
I think you need to specify the content type as JSON (as Ive seen from my experience)
var is_where = true;
$.ajax({
type: 'POST',
url: '/api/airport/getListItems',
data: is_where,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(data) {
}
});
The Value your passing is Bool, pls change your method signature to :
public class AirportClass{
public List<AirportClass> getListItems(bool where){
}
}

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