简体   繁体   中英

How to keep original values of an entity while reloading related entities using Entity Framework Core when ModelState is not valid?

Using ASP.NET Core and Entity Framework Core.

When editing a record, I also load related "child" entities used for display purposes in the edit form.

If the user submits a form with missing required fields, then ModelState.IsValid is false. So far so good.

When returning the non-updated values to the user (with an error message), how can I keep the original values posted by the user and also reload related entities?

In the following simplified example the dbcontext queries the client record and includes the associated state table to display the state name.

If the ModelState is not valid, the client record is returned to the user with the values the user submitted - but all the related .Include entities are null at this point. How can I repopulate the .Include entities without overwriting the view model submitted?

// GET
public async Task<IActionResult> Edit(int clientId)
{
    var client = _context.Client
                         .Include(x => x.State)
                         .Where(w => w.client_id == clientId
                         .FirstOrDefault();
    return View(client);
}

// POST
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(clientModel)
{
   //verify: last_name
   if (clientModel.last_name == null)
   {
       ModelState.AddModelError(string.Empty, "Last name is required");
   }

   if (ModelState.IsValid)
   {
      // Update the record and redirect
      await _context.SaveChangesAsync();
      return RedirectToAction(nameof(Index), new { client_id = clientModel.client_id });
   }

   // model state is not valid! Return record submitted to the edit view
   // *** MISSING THE VALUES FROM THE RELATED ENTITY clientModel.State at this point
   return View(clientModel);
}

First the State navigation property should be virtual then you can load it using await _context.Entry(clientModel).Reference(x => x.State).LoadAsync();

if the related is a collection then you can use await _context.Entry(clientModel).Collection(x => x.Collection).LoadAsync();

another way is to get data from context and assign it

var client = _context.Client
                         .Include(x => x.State)
                         .Where(w => w.client_id == clientId
                         .FirstOrDefault(); 


 //or just get the state .. var state = _context.State..
clientModel.State = client.State;
return View(clientModel);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM