ASP.NET MVC Model Binding with jQuery ajax request

。_饼干妹妹 提交于 2020-12-29 04:43:45

问题


I have a server side object in my MVC code that looks like this:

class Person
{
  public long Id { get; set; }

  public string Name { get; set; }

  public IList<Friend> Friends { get; set; } 
}

class Friend
{
  public long Id { get; set; }

  public string Name { get; set; }
}

From the jQuery client, I am making an ajax request and sending the following data (line breaks introduced for readability):

var personId = $(...
var personName = $(...

var friends = []; // array of associative arrays

for (var i = 0; i < _friends.length; i++) // _friends is is a global array object and is different from friends below
{
  var friendId = $(...
  var friendName = $(...)

  friends[i] = { 'Id' : friendId, 'Name' : friendName };
}

... and so on to get values into variables

Please observe that I am sending what should go into Person.Friends, the IList<T> as a JavaScript array where each element of the array is an associative list that has properties just like the server side Friend class.

Here's my ajax request:

$.ajax('/Strings/JsonCreateNew', 
  { 
    cache: false, async: false, type: 'POST', 
    data: { 
        'Id' : personId, 
        'Name' : personName, 
        'Friends' : friends}, 
    dataType: 'json', 
    error: SaveNewFriendClientSideHandler.OnError, 
    success: SaveNewFriendClientSideHandler.OnSuccess 
  });

In my controller, as long as I have a FormCollection to receive the data, I get all my data, but I'd like to bind to the strongly typed Person object, so if I change my controller definition from:

[HttpPost]
public ActionResult JsonCreateNew(FromCollection person)
{
  // I get all the data in the person.AllKeys property
  return new EmptyResult();
}

to:

[HttpPost]
public ActionResult JsonCreateNew(Person person)
{
  // the default ASP.NET MVC model binder isn't able to bind to this
  // in fact, the routing module does not even route the request to this
  // action, so this action never gets fired.
  return new EmptyResult();
}

I still do get all my data but I am really still concerned about the IList<Friend>.

It is received in the Person object as an array that has the correct number of Friends objects with the right property names (Name and Id) but the values of both the properties of each Friend object are null or 0, i.e. not initialized even when there are values being sent by the client.

Please help.


回答1:


There is a bug in MVC they refuse to fix that if the colection property name begins with the type name it does not bind. Change

    public IList<Friend> Friends { get; set; } 

To:

    public IList<Friend> Biscuits { get; set; } 

just temporary. It will work.




回答2:


You have to specify the content type: contentType: "application/json". @MohammadRB solution contains it, but it should work even if you don't stringify the post data.




回答3:


I think it will work:

var p = { 'Id' : personId, 'Name' : personName, 'Friends' : friends };
$.ajax('/Strings/JsonCreateNew', 
  { 
    type: 'POST', 
    data: JSON.Stringify({ person : p }), 
    contentType : "application/json",
    dataType: 'json', 
    error: SaveNewFriendClientSideHandler.OnError, 
    success: SaveNewFriendClientSideHandler.OnSuccess 
  });

Also i prefer IEnumerable<> instead of IList<> if you only want iterate over them

Edit Test case :

var friends = new Array();
friends.push({ Id: "1", Name: "A" });
friends.push({ Id: "2", Name: "B" });
var p = { 'Id': 5, 'Name': "Mohammad", 'Friends': friends };

$(document).ready(function () {

  $.ajax('/Home/JsonCreateNew',
  {
      type: 'POST',
      data: JSON.stringify({ person: p }),
      contentType: "application/json",
      dataType: 'json',
      error: function () { alert("f"); },
      success: function () { alert("s"); }
  });

});


来源:https://stackoverflow.com/questions/19299008/asp-net-mvc-model-binding-with-jquery-ajax-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!