Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core MVC Mixed Route/FromBody Model Binding & Validation

Tags:

I am using ASP.NET Core 1.1 MVC to build an JSON API. Given the following model and action method:

public class TestModel {     public int Id { get; set; }      [Range(100, 999)]     public int RootId { get; set; }      [Required, MaxLength(200)]     public string Name { get; set; }      public string Description { get; set; } }  [HttpPost("/test/{rootId}/echo/{id}")] public IActionResult TestEcho([FromBody] TestModel data) {     return Json(new     {         data.Id,         data.RootId,         data.Name,         data.Description,         Errors = ModelState.IsValid ? null : ModelState.SelectMany(x => x.Value.Errors)     }); } 

The [FromBody] on my action method parameter is causing the model to be bound from the JSON payload that is posted to the endpoint, however it also prevents the Id and RootId properties from being bound via the route parameters.

I could break this up into to separate models, one bound from the route and one from the body or I could also force any clients to send the id & rootId as part of the payload, but both of those solutions seem to complicate things more than I'd like and don't allow me to keep the validation logic in a single place. Is there any way to get this situation working where the model can be bound properly and I can keep my model & validation logic together?

like image 690
heavyd Avatar asked Aug 03 '17 22:08

heavyd


People also ask

How do I bind a model to view in MVC core?

How does model binding work in ASP.NET Core MVC. In an empty project, change Startup class to add services and middleware for MVC. Add the following code to HomeController, demonstrating binding of simple types. Add the following code to HomeController, demonstrating binding of complex types.

What is difference between FromQuery and FromBody?

[FromQuery] - Gets values from the query string. [FromRoute] - Gets values from route data. [FromForm] - Gets values from posted form fields. [FromBody] - Gets values from the request body.

What is two way binding MVC?

So the two-way data binding means we can perform both read and write operations. In our previous article Data Binding in Spring MVC with Example, we have discussed how to write-to-variable task and in this article, we mainly focus on the read-from-a-variable task.


1 Answers

  1. Install-Package HybridModelBinding

  2. Add to Statrup:

    services.AddMvc()     .AddHybridModelBinder(); 
  3. Model:

    public class Person {     public int Id { get; set; }     public string Name { get; set; }     public string FavoriteColor { get; set; } } 
  4. Controller:

    [HttpPost] [Route("people/{id}")] public IActionResult Post([FromHybrid]Person model) { } 
  5. Request:

    curl -X POST -H "Accept: application/json" -H "Content-Type:application/json" -d '{     "id": 999,     "name": "Bill Boga",     "favoriteColor": "Blue" }' "https://localhost/people/123?name=William%20Boga" 
  6. Result:

    {     "Id": 123,     "Name": "William Boga",     "FavoriteColor": "Blue" } 
  7. There are other advanced features.

like image 105
Mentor Avatar answered Sep 28 '22 10:09

Mentor