MVC 3 - JSON serializer

I have the following model, view, and controller.

Model

public class Person { public string Name;// { get; set; } public string Occupation { get; set; } public int Salary { get; set; } public int[] NumArr { get; set; } } 

View

 <input type="button" id="Test" value="Test" /> @section Javascript{ <script type="text/javascript"> $(function () { $("#Test").click(function () { var data = { Name: "Michael Tom", Occupation: "Programmer", Salary: 8500, NumArr: [2,6,4,9] }; var url = "Home/GetJson"; $.ajax({ url: url, dataType: "json", type: "POST", data: data, traditional: true, success: function (result) { } }); }); }); </script> } 

Controller

 public class HomeController : Controller { public ActionResult Index() { return View(); } public JsonResult GetJson(Person person) { return Json(......); } } 

Based on the code above, I like to ask three questions.

  • If we use a public field instead of properties, the serializer does not serialize the json object to the C # model, so I always get null for the "Name" field in the controller. Why it happens?

  • If I change the type of the NumArr property to List, this will not work. How can we use List instead of int []? I know that I am passing an array from JS. Can we pass List from JS?

  • I use "traditional: true" in the Javascript View code block because serialization does not work with "traditional: false". I heard jQuery has three versions of the Json serializer. The ASP.NET MVC serializer only supports the old version. It's true?

3.1. If this is true, I like to know when you are going to get the latest version of the MVC serializer, which supports the latest version of jQuery.

3.2. Is there a way to register a custom Javascript Serializer in the same way that we can register a custom viewer? My friend suggested that I could register a custom value provider or custom mediator and use my own JS serializer in my custom vendor / model mediator.

Thanks in advance. Please feel free to let me know if you do not know about my questions. Thank you

+4
json jquery asp.net-mvc-3 jsonserializer
source share
1 answer

1) If we use a public field instead of properties, the serializer does not serialize the json object to the C # model, so I always get null for the Name field in the controller. Why it happens?

Because the model binder only works with properties. This is by design. Usually, fields should be private in your classes. This is an implementation detail. Use properties to expose some kind of behavior to the outside world.

2) If I changed the type of the NumArr property to List, then it does not Work. How can we use List instead of int []? I know that I am passing an array from JS. Can we pass List from JS?

It should work. Regardless of whether you use List<int> , IEnumerable<int> or int[] , this also works. Whatever happens if you wanted to use a collection of some complex object, for example, List<SomeComplexType> (see My answer below for solving this question).

3) I use "traditional: true" in the Javascript View code block because Serialization does not work with "traditional: false". I heard this jQuery has three versions of the Json serializer. The ASP.NET MVC serializer only supports the old version. It's true?

Yes, the traditional parameter was introduced in jQuery 1.4 when they changed the way serialization of jQuery parameters. This change turned out to be incompatible with the standard convention that the middleware uses in MVC when binding to lists .

So, download the javascript debugging tool like FireBug and start playing. You will see differences in how jQuery sends a query when this parameter is set.


All this suggests that I recommend that you send JSON-encoded requests for the actions of your controller. This will work with any complex objects, and you do not need to ask yourself which version of jQuery you are using or something else, because JSON is a standard compatible format. The advantage of the standard interoperable format is that no matter what system you use, you should be able to make them speak the same language (unless, of course, there are errors in these systems and they do not follow a specific standard).

But now you could tell me that application / x-www-form-urlencoded is also a standard and non-integrable format. And it is true. The problem is that the model’s middleware uses convention when binding the name of input fields to the properties of your models. And this convention is far from being compatible or standard.

So, for example, you might have a hierarchy of models:

 public class Person { public string Name { get; set; } public string Occupation { get; set; } public int Salary { get; set; } public List<SubObject> SubObjects { get; set; } } public class SubObject { public int Id { get; set; } public string Name { get; set; } } 

You can imagine any complex hierarchy that you like (with the exception of circular links that are not supported by the JSON format).

and then:

 var data = { name: "Michael Tom", occupation: "Programmer", salary: 8500, subObjects: [ { id: 1, name: 'sub 1' }, { id: 2, name: 'sub 2' }, { id: 3, name: 'sub 3' } ] }; $.ajax({ url: "Home/GetJson", type: "POST", data: JSON.stringify({ person: data }), contentType: 'application/json', success: function (result) { } }); 

We set the HTTP header of the Content-Type request to application/json to indicate to the built-in JSON value provider that the request is JSON encoded (using the JSON.stringify method) and it will parse it back to your highly typed model. The JSON.stringify method JSON.stringify built into modern browsers, but if you want to support legacy browsers, you can include the json2.js script in your page.

+14
source share

All Articles