1

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?

Community
  • 1
  • 1
xabush
  • 849
  • 1
  • 13
  • 29
  • if `talents` is collection then do not wrap `talents` with `{}`, do pass data directly `data: talents` – Pankaj Parkar Mar 19 '16 at 10:54
  • 1
    Note that you're using the _legacy_ promise syntax `success`, `error`, use the `then` method instead as described here (https://docs.angularjs.org/api/ng/service/$http) – glcheetham Mar 19 '16 at 11:13
  • @PankajParkar, You're right! That was the problem. Add your comment as an answer so that I can accept it. – xabush Mar 19 '16 at 11:14

1 Answers1

1

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"
})
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • What if talents was a simple object? Do we still need to remove the curly braces? When is it appropriate to use curly braces when sending ajax data? – xabush Mar 19 '16 at 11:31
  • @avidProgrammer see, you have to send data from client to server in expected format.. like here server is accept collection of `talent` where as you already had that on client end which is `talents` which is working. Now I'm coming to your question.. Yes.. you should to make it as an array and then pass it to the server something like `[].concat(talent)` would work – Pankaj Parkar Mar 19 '16 at 11:34