5

My Controller is able to create the model object but all the properties related to model and assigned to null values

Environment : VS 2010, ASP.NET MVC RC latest, jQuery 1.7.1

Following is the Web API Controller code

public class Customer
{
    public string Name { get; set; }
    public string City { get; set; }
}
public class UserController : ApiController
{
    public Customer Post(Customer user)
    {
        return user;
    }
}

Following is the ajax calling code

$.ajax('/api/user',
{
  ContentType: "application/x-www-form-urlencoded; charset=UTF-8",
  dataType: 'json',
  type: 'POST',
  data: JSON.stringify({ "Name": "Scott", "City": "SC" })
});

Controller does create the model "Customer" object but both "Name" and "City" properties are null.

What's wrong here?

I have read many similar issues on this site but could not find the solution.

afuzzyllama
  • 6,538
  • 5
  • 47
  • 64
user1901680
  • 81
  • 1
  • 3
  • Since the class name is `Customer`, I would say you need to have the passed in data encapsulated in a `Customer` property as well. `{"Customer" : { "Name": "Scott", "City": "SC" }}`. – Oded Dec 29 '12 at 18:38
  • Thanks for the quick response. I don't think we need to pass the class name. Any way tried it and I have the same problem. I have tried {"user" : { "Name": "Scott", "City": "SC" }} too as user is the parameter name. – user1901680 Dec 29 '12 at 18:51
  • After few trails, I have modified the ajax code to $.ajax('/api/user', { ContentType: "application/x-www-form-urlencoded; charset=UTF-8", dataType: 'json', type: 'POST', data: { "Name": "Scott", "City": "SC"} }); I removed the JSON.stringify and it worked. – user1901680 Dec 29 '12 at 20:04
  • Write that up as the answer - `JSON.stringify` is not needed... – Oded Dec 29 '12 at 20:05
  • 4
    The problem was that you were trying to post a JSON string embedded in form URL encoded data. You should be choosing one or the other. Either you send raw JSON and you use the "application/json" media type, or you send form URL encoded data using "application/x-www-form-urlencoded". See http://stackoverflow.com/questions/5570747/jquery-posting-json for someone that made the same mistake. – Youssef Moussaoui Dec 30 '12 at 05:13
  • By the way, if something goes wrong in deserialization, it can help to look at the model state errors to see what went wrong. – Youssef Moussaoui Dec 30 '12 at 05:14

4 Answers4

2

This blog here gives a good idea about how Model Binding differs in ASP.NET Web project and a ASP.NET Web API project.

I was facing a similar issue in the project I was working on and adding a explicit ModelBinding attribute made the property values stick

Requested Data :

var customer  = { Name : "customer Name", City : "custome City" }

$.ajax({ 
   url : ...
   type: ...
   data : customer
});

Request Class:

public class Customer
{
    public string Name { get; set; }
    public string City { get; set; }
}

Controller :

public class UserController : ApiController
{
    [HttpGet]
    public Customer Get([ModelBinder] Customer user)
    {
        // fetch from whereever
    }
}
frictionlesspulley
  • 11,070
  • 14
  • 66
  • 115
1

I'm going through the same issue right now. I'm not 100% sure of the answer, but below is my javascript and I've added to the class [DataModel] and to the Properties [DataMember]. That is:

    [DataModel]
    public class Customer
    {
      [DataMember] public string Name { get; set; }
      [DataMember] public string City { get; set; }
    }

And My JavaScript

        $(document).ready(function () {
        // Send an AJAX request
        $.getJSON("api/session/GetAll",
        function (data) {
            // On success, 'data' contains a list of products.
            $.each(data, function (key, val) {

                //debugger;

                // Format the text to display.
                //var str = val.Name + ': $' + val.Price;
                var str = 'abcd';

                // Add a list item for the product.
                $('<li/>', { text: str })
                .appendTo($('#products'));
            });
        });
    });
Peter Kellner
  • 14,748
  • 25
  • 102
  • 188
0

Faced a similar issue and my problem turned out to be invalid JSON in the body of the request. There was a comma missing after one of the fields. So it seems like the default model binder just binds null if there are any syntax errors in the JSON.

John
  • 3,512
  • 2
  • 36
  • 53
0

Next time this happens, ensure that there is no "internal" keyword on the property setter. That is: instead of public string Comment {get; internal set;} use public string Comment {get; set;}

This fixed it for me.

Tobaj
  • 1
  • 1