Adam Szabo
Adam Szabo

Reputation: 11412

Model binder not working with JSON POST

I'm sending the following JSON via a POST:

POST http://localhost:52873/news 

{"text":"testing","isPublic":true}

My controller:

public class NewsController : Controller
{
    // GET: /<controller>/
    [HttpGet]
    public IActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public IActionResult Post(CreatePostCommand command)
    {
        /* ...more code... */
        return new HttpStatusCodeResult(200);
    }
}

And the command is:

public class CreatePostCommand
{
    public string Text { get; set; }
    public bool IsPublic { get; set; }
}

My route setup is the default which comes with the MVC template in VS 2014 CTP 4:

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default", 
        template: "{controller}/{action}/{id?}",
        defaults: new { controller = "Home", action = "Index" });

    routes.MapRoute(
        name: "api",
        template: "{controller}/{id?}");
});

Quote from Getting Started with ASP.NET MVC 6:

Using this route template, the action name maps to the HTTP verb in the request. For example, a GET request will invoke a method named Get, a PUT request will invoke a method named Put, and so forth. The {controller} variable still maps to the controller name.

This doesn't seem to work for me. I'm getting 404 error. What am I missing with this new ModelBinder? Why doesn't it bind my JSON POST message?

Upvotes: 2

Views: 2086

Answers (1)

Adam Szabo
Adam Szabo

Reputation: 11412

It works after

  • removing [HttpPost] attribute, and
  • adding [FromBody] attribute before attribute type.

The corrected code:

// No HttPost attribute here!
public IActionResult Post([FromBody]CreatePostCommand command)
{
    /* ...more code... */
    return new HttpStatusCodeResult(200);
}

Upvotes: 5

Related Questions