Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POST JSON with MVC 4 API Controller

I have this code:

   $.ajax({


        type: "POST",
        url: "/api/slide",
        cache: false,
        contentType: "application/json; charset=utf-8",
        data: '{"Title":"fghfdhgfdgfd"}',
        dataType: "json",

An this is my controler:

public class SlideController : ApiController
{

    // POST /api/Slide
    public void Post(string Title)
    {
    }

When I run the code and call the /api/Slide, the [Title] has no data and is null.

How do I post JSON to the API controller?

POST http://127.0.0.2:81/api/slide HTTP/1.1
Host: 127.0.0.2:81
Connection: keep-alive
Content-Length: 18
Origin: http://127.0.0.2:81
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1
Content-Type: application/json; charset=UTF-8
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://127.0.0.2:81/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

Title=fghfdhgfdgfd
like image 439
user1615362 Avatar asked Sep 16 '12 10:09

user1615362


People also ask

How can we post data in a JSON format to a Web API from a MVC controller?

You need to use JSON. stringify method to convert it to JSON string when you send it, And the model binder will bind the json data to your class object. contentType property tells the server that we are sending the data in JSON format.

How do I post JSON to a REST API endpoint?

To post JSON to a REST API endpoint, you must send an HTTP POST request to the REST API server and provide JSON data in the body of the POST message. You also need to specify the data type in the body of the POST message using the Content-Type: application/json request header.

How do you post to a Web API controller from an MVC controller?

In order to add a Web API Controller you will need to Right Click the Controllers folder in the Solution Explorer and click on Add and then Controller. Now from the Add Scaffold window, choose the Web API 2 Controller – Empty option as shown below. Then give it a suitable name and click OK.


2 Answers

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.

like image 88
Darin Dimitrov Avatar answered Oct 21 '22 21:10

Darin Dimitrov


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 
}
like image 40
Isioma Nnodum Avatar answered Oct 21 '22 20:10

Isioma Nnodum