Mvc: TryUpdateModelAsync() doesn't work for ASP.NET Core MVC Web API

Created on 5 Jan 2017  路  3Comments  路  Source: aspnet/Mvc

I'm creating a simple mvc web api demo as follows.

```c#
[HttpPut("{id}")]
public async void Put(int id, [FromBody]Student student)
{
if (ModelState.IsValid)
{
var stu = _context.Students
.Where(s => s.StudentId == id)
.SingleOrDefault();

        var updateResult = await TryUpdateModelAsync<Student>(stu, "", s => s.FirstName, s => s.LastName, s => s.EnrollmentDate);
        _context.SaveChanges();
    }

}
The HTTP request to test the method is:

```json
PUT /api/Student/2 HTTP/1.1
Host: localhost:5207
Content-Type: application/json
Cache-Control: no-cache

{
  "studentId": 2,
    "firstName": "Tony",
    "lastName": "Black",
    "enrollmentDate": "2016-12-21T00:00:00"
  }

The problem is that TryUpdateModelAsync doesn't work, no properties in stu object got updated with corresponding properties from student object (the incoming parameter).

I wonder:

  1. If TryUpdateModelAsync can be used in MVC Web API?
  2. I really don't want to write boring code like the following, how do I avoid doing the property value settings from one object to another of the same type? (that's the very first reason why I used TryUpdateModelAsync)

c# stu.FirstName = student.FirstName; stu.LastName = student.LastName; stu.SomeOtherProperties = student.SomeOtherProperties; _context.SaveChanges();

.NET Core version: 1.1.0 ASP.Net Core version: 1.1.0 Entity Framework Core version: 1.1.0

Most helpful comment

Thanks for the thorough suggestions, I am gonna go with the 3rd option.

One of big benefits of open source project is that we can directly communicate with the Dev teams, skipping the first line of support who seems not touch the core of the product. I really liked this way of interaction and support model. Thank you again.

All 3 comments

The [FromBody] attribute uses formatters to deserialize the request body into an object (e.g. using JSON or XML).

On the other hand, model binding, which includes the TryUpdateModel API, uses value providers to get data from the form body (if any), query string, route data, or some other places.

There are a few ways to go here:

  1. You could certainly write the "boring" code. Or you could look at using a library such as AutoMapper that does this "left-hand/right-hand" operation automatically.
  2. You could change the posted data to be a form post, in which case model binding will work just fine.
  3. You could change the posted data to use the JSON PATCH protocol, which was created for exactly this scenario. There's a great blog post about how to do that with ASP.NET Core: http://benfoster.io/blog/aspnet-core-json-patch-partial-api-updates

Thanks for the thorough suggestions, I am gonna go with the 3rd option.

One of big benefits of open source project is that we can directly communicate with the Dev teams, skipping the first line of support who seems not touch the core of the product. I really liked this way of interaction and support model. Thank you again.

Thanks for your kind comments!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nefcanto picture nefcanto  路  3Comments

workmonitored picture workmonitored  路  3Comments

DamianEdwards picture DamianEdwards  路  3Comments

iXmonvi33 picture iXmonvi33  路  4Comments

Mr-Smileys picture Mr-Smileys  路  3Comments