Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's happening in TryUpdateModelAsync

So I'm doing this microsoft tutorial on ASP.NET Core with EF 6 and it just went through updating a model through the edit-controller.

There is this piece of code that have me really confused that I imagine (and perhaps hope) isn't as confusing to a lot of you.

var studentToUpdate = await _context.Students.SingleOrDefaultAsync(s => s.ID == id);

if (await TryUpdateModelAsync<Student>(
          studentToUpdate, 
          "", 
           s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate))
// goes on to save the context

So, the only thing this controller takes as parameter is the int id and that's how it gets a hold of the studentToUpdate. What I'm not entirely familiar with here, is where does it get the update-values from?

What I know:

  • TryUpdateModelAsync<Student>
    • first argument: model to update
    • second argument: prefix (?) from reference: The prefix to use when looking up values in the .
    • third argument: a linq-statement which I suspect is related to the solution I'm looking for.
  • Ran the debugger and before the function was executed studentToUpdate.FirstMidNames was Carson(original) but after the function had been executed it was Carsey(new). The string Carsey was always in the this>Request>Form>Results View (which held a list of all the values from the form).

So I understand that the TryUpdateModelAsync function somehow uses the linq-statement and the form-result to get the new values for studentToUpdate, but I really don't see how and where it does this?

like image 791
MrJalapeno Avatar asked Jun 15 '17 12:06

MrJalapeno


2 Answers

Without going into too much technical details. The call to TryUpdateModelAsync in the provided example

if (await TryUpdateModelAsync<Student>(
      studentToUpdate, 
      "", 
       s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate)){
    //...
}

Updates the specified Student instance studentToUpdate using values from the controller's current ControllerContext, which would have been populated with data provided in the request. It uses lambda expression(s) which represent top-level properties which need to be included for the current model when trying the update. It will take only the values of those properties and update the model.

So in the above example even if the entire model was provided by the form it will only update the FirstMidName, LastName, and EnrollmentDate on the specified instance.

like image 192
Nkosi Avatar answered Nov 16 '22 01:11

Nkosi


I think the most confusing thing about this is Third argument: a linq-statement.

Every linQ expression [i => i.property] will match with each column inside table or the constraint (Foreign Key, Index,...) (what we know as navigation properties in EF MVC).

So, Third argument decides what should be updated (async) to the Datebase. And it does this via model binding Link to model binding

like image 1
Point Avatar answered Nov 16 '22 01:11

Point