Treker
Treker

Reputation: 398

ASP.NET MVC 5 - Model Binding Not Working

I am having trouble binding incoming JSON data in the body of an HTTP POST request to my C# model.

Here is my front-end JavaScript code:

let jsonData = "{\"Updates\":[{\"CarrierStateMapGuid\":\"de4abaa8-42d2-4e00-657a08d5577ac94a\",\"QuestionTag\":\"CoQstPAVT500006\",\"MemberOf\":\"Quote\",\"Condition\":\"0\",\"QuestionType\":\"List\",\"TrueAnswer\":\"NoDiscount\",\"TrueExplanation\":\"No Discount\",\"FalseAnswer\":null,\"FalseExplanation\":null,\"DeleteRequest\":false}]}";
$.ajax({
    url: "/api/CarrierQuestionMappingApi/UpdateQuestionMaps",
    type: "POST",
    contentType: "application/json; charset=utf-8",
    data: jsonData
});

Here is my C# model:

public class UpdateCarrierQuestionMapsWebRequests
{
    public UpdateCarrierQuestionMapsWebRequest[] Updates { get; set; }

    public class UpdateCarrierQuestionMapsWebRequest
    {
        public string CarrierStateMapGuid { get; set; }
        public string QuestionTag { get; set; }
        public string MemberOf { get; set; }
        public string Condition { get; set; }
        public string QuestionType { get; set; }
        public string TrueAnswer { get; set; }
        public string TrueExplanation { get; set; }
        public string FalseAnswer { get; set; }
        public string FalseExplanation { get; set; }
        public bool DeleteRequest { get; set; }
    }
}

Here is my back-end C# controller code:

[HttpPost]
[Route("api/[controller]/UpdateQuestionMaps")]
public HttpResponseMessage UpdateQuestionMaps(UpdateCarrierQuestionMapsWebRequests request)
{
     // request.Updates is null
}

I cannot figure out why request.Updates is null and is not getting set by the model binder.

Upvotes: 3

Views: 1628

Answers (2)

Blaine
Blaine

Reputation: 126

The problem has to-do with AJAX and ASP.NET MVC. MVC doesn't like any serialization from AJAX. When you pass AJAX an object, it manually serializes it and MVC expects to deserialize it in the manner AJAX serializes it. So any manual serialization will break this process. In your method above you are ending up with an encoded string. However if you change your AJAX call to:

let jsonData = "[{\"CarrierStateMapGuid\":\"de4abaa8-42d2-4e00-657a08d5577ac94a\",\"QuestionTag\":\"CoQstPAVT500006\",\"MemberOf\":\"Quote\",\"Condition\":\"0\",\"QuestionType\":\"List\",\"TrueAnswer\":\"NoDiscount\",\"TrueExplanation\":\"No Discount\",\"FalseAnswer\":null,\"FalseExplanation\":null,\"DeleteRequest\":false}]";
$.ajax({
    url: "/api/CarrierQuestionMappingApi/UpdateQuestionMaps",
    type: "POST",
    contentType: "application/json; charset=utf-8",
    data: {
         Updates: jsonData
    }
});

The data will be sent as form data and properly serialize on the controller.

Upvotes: 5

Ehsan Sajjad
Ehsan Sajjad

Reputation: 62488

There are couple of adjustements that you can do. Firstly you can use List<T> instead of array and then in the parameterless constructor instantiate it:

public class UpdateCarrierQuestionMapsWebRequests
{
    public List<UpdateCarrierQuestionMapsWebRequest> Updates { get; set; }

    public UpdateCarrierQuestionMapsWebRequests()
    {
       Updates = new List<UpdateCarrierQuestionMapsWebRequest>();
    }

   public class UpdateCarrierQuestionMapsWebRequest
   {
        public string CarrierStateMapGuid { get; set; }
        public string QuestionTag { get; set; }
        public string MemberOf { get; set; }
        public string Condition { get; set; }
        public string QuestionType { get; set; }
        public string TrueAnswer { get; set; }
        public string TrueExplanation { get; set; }
        public string FalseAnswer { get; set; }
        public string FalseExplanation { get; set; }
        public bool DeleteRequest { get; set; }
    }
}

and in your view before sending the request you can stringify your json which would be like:

data: JSON.stringify(jsonData)

Hope it will help!

Upvotes: 0

Related Questions