Search code examples
c#angularjsjsonasp.net-mvcangularjs-http

Complex object not getting bound to JSON data


I have two ViewModel objects TalentViewModel and EditTalentViewModel. Here are their respective codes:

TalentViewModel

public class TalentViewModel
{
    [JsonProperty(PropertyName = "TalentId")]
    public long TalentId { get; set; }
    [JsonProperty(PropertyName = "TalentName")]
    public string TalentName { get; set; }
}

EditTalentViewModel

public class EditTalentViewModel
{
    [JsonProperty(PropertyName = "AddedTalents")]
    public List<TalentViewModel> AddedTalents { get; set; } 
    [JsonProperty(PropertyName = "RemovedTalents")]
    public List<TalentViewModel> RemovedTalents { get; set; } 
}

I send a json data to a action method, which accepts EditTalentViewModel as a parameter, using ajax call. Here is the angularJs code that sends the ajax request

//this will send the json data to InterestController
$scope.saveInterest = function (talents) {
    $http({
        method:"POST",
        url:"/Interest/AddTalents",
        data: {talents},
        headers: {
            'Content-type': "application/json"
        },
        responseType:"json"
    }).success( function(data){
        console.log(data);

    }).error( function(data){
        console.log("Error happening");
    });
}

I used a custom model binder suggested in this answer and used it to as my model binder for EditTalentViewModel object. Here is the part of the action method:

[HttpPost]
public ActionResult AddTalents([ModelBinder(typeof(JsonModelBinder))]EditTalentViewModel talents)
{
    if (!ModelState.IsValid) return Json("Fail");
    var userId = User.Identity.GetUserId<long>();
    if (talents.AddedTalents == null && talents.RemovedTalents == null)
    {
        return Json("Success");
    }
    //.........
}

And a sample of the JSON data being sent to looks like this:

{
    "AddedTalents": [{
        "TalentId": 10,
        "TalentName": "Sculptor"
    }, {
        "TalentId": 8,
        "TalentName": "Painter"
    }],
    "RemovedTalents": [{
        "TalentId": 2,
        "TalentName": "Dj"
    }]
}

However, when I debug my code, the AddedTalents and RemovedTalents properties of EditViewModel class are null. What am I missing here? How can I solve this problem? Also is there is a better way of doing the model binding?


Solution

  • talents is collection of object which you wanted to POST to server as request body. So the mistake is you you had wrap talents with {} which isn't required as talents is collection of object already.

    $http({
        method:"POST",
        url:"/Interest/AddTalents",
        data: talents, //<--change here, removed unwanted {}
        headers: {
           'Content-type': "application/json"
        },
        responseType:"json"
    })