POST JSON with MVC 4 API Controller POST JSON with MVC 4 API Controller ajax ajax

POST JSON with MVC 4 API Controller


Define a view model:

public class SlideViewModel{    public string Title { get; set; }}

then have your controller action take this view model as argument:

public class SlideController : ApiController{    // POST /api/Slide    public void Post(SlideViewModel model)    {        ...    }}

finally invoke the action:

$.ajax({    type: 'POST',    url: '/api/slide',    cache: false,    contentType: 'application/json; charset=utf-8',    data: JSON.stringify({ title: "fghfdhgfdgfd" }),    success: function() {        ...        }});

The reason for that is that simple types such as strings are bound from the URI. I also invite you to read the following article about model binding in the Web API.


Ensure the object you are trying to convert to has a default (empty) constructor.

Rule of thumb: If you want to deserialize to an object, you need to make it simple for the objects to be created. These guidelines can help:

  • All properties that are to be passed around must be public

  • the object needs to able to be constructed without any parameters.

This JSON string/object for example:

{ Name: "John Doe", Phone: "123-456-7890", Pets: [ "dog", "cat", "snake" ] }

can be converted to an object from the following class:

 public class Person {     public string Name { get; set; }     public string Phone { get; set; }     public string[] Pets { get; set; }  }

or this one:

public class Person {   public string Name { get; set; }   public string Phone { get; set; }   public string[] Pets { get; set; }   public Person() {}   public Person(string name, string phone) {      Name = name;      Phone = phone;   }}

or this one:

public class Person {    public string Name { get; set; }    public string Phone { get; set; }    public string[] Pets { get; set; }    public Person() {} }

but not this one

public class Person {    public string Name { get; set; }    public string Phone { get; set; }    public string[] Pets { get; set; }    public Person(string name, string phone) {      Name = name;      Phone = phone;    }}

Now let ASP.NET MVC 4 do the rest

public class PersonController : ApiController{        // .. other actions         public HttpResponseMessage PostPerson(Person person)        {            if ( null != person)                // CELEBRATE by doing something with your object            else                 // BE SAD and throw and exception or pass an error message        }        // .. other actions }

If your class cannot have a default constructor or if you don't have access to the source code for the class, you can create an adapter class that

  • has a default constructor
  • exposes those properties that need to be public

Using the Person class above with no default constructor, an adapter could look like

public class PersonAdapter {    public Person personAdaptee;    public string Name {        get { return personAdaptee.Name; }        set { personAdaptee.Name = value }    }    public string Phone {        get { return personModel.Phone; }        set { personModel.Phone = value; }    }    public string[] Pets {        get { return personAdaptee.Pets; }        set {personAdaptee.Pets = value }    }    public PersonAdapter() {        personAdaptee = new Person("", "", null);    }}

Now let ASP.NET MVC 4 do the rest

public class PersonController : ApiController{        // .. other actions         public HttpResponseMessage PostPerson(PersonAdapter person)        {            if ( null != person)                // CELEBRATE by doing something with your object            else                 // BE SAD and throw and exception or pass an error message        }        // .. other actions }


Try this:

$.ajax({    type: "POST",    url: "/api/slide",    data: { Title: "fghfdhgfdgfd" }});

It is the quotes around the data attribute which are causing this:

i.e >> data: { Title: "fghfdhgfdgfd" }
not >> data: '{ Title: "fghfdhgfdgfd" }'

UPDATE:
Also your controller seems a little strange, although it is hard to tell without seeing your routing, etc.

I would expect to see something more like this:

public class SlideController : ApiController{    public HttpResponseMessage PostSlide(string Title)    {        // Do your insert slide stuff here....        string uri = Url.Link("DefaultApi", new { id = item.Id });        response.Headers.Location = new Uri(uri);        return response;    }}

Clearly, you will also need to update the URL in your jQuery too.

Take a look here:

http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api

ANOTHER UPDATE:

It would be usual to create a CLR object to match your Json and use the MVC model binder to bind directly to that. If you don't want to do that you can bind to an object and deserialize into a Dictionary:

// POST api/valuespublic void Post(object json){    Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json.ToString());    var x = values["Title"];}