question

VC-2058 avatar image
0 Votes"
VC-2058 asked FeiHan-MSFT commented

Application crashes when passing ViewModel to the Controller

When I pass the view model to the method it crashes but it works with FormCollection or not passing anything to the onpost method.

Below is the code:

[HttpPost]
[AutoValidateAntiforgeryToken]
public ActionResult Update(CustomerInformation model)
{
if (ModelState.IsValid)
{
//save
var UpdateRecord = customerServices.Update(model);
if (UpdateRecord)
{
return RedirectToAction("Details");
}
}
}

@model Customer.Models.CustomerInformationDetails
@using Customer.Models.CustomerInformation

@{
var customerName = Model.Name;
ViewData["Title"] = customerName;
}

<h1>Edit information for @customerName</h1>
<hr />
@using (Html.BeginForm("Update",
"Customer",
FormMethod.Post))
{
<div class="form-group">
@Html.Label("Introduction", "Introduction:", htmlAttributes: new { @class = "control-label col-md-10" })
<div class="col-md-10">
@Html.EditorFor(model => model.Introduction, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.Label("Contact Person", "Contact Person:", htmlAttributes: new { @class = "control-label col-md-10" })
<div class="col-md-10">
@Html.EditorFor(model => model.ContactPerson, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
<input type="submit" value="Update" class="btn btn-primary"></input>
</div>
}

dotnet-csharpdotnet-aspnet-core-general
· 13
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I strongly recommend that you try debugging the code on your own using the Visual Studio debugger. Verify the Update action executes and the model state. Is the model valid? As written the logic does nothing if the model is invalid. You'll want to at least return the model validation errors as shown below.

Lastly, try going through the getting started tutorials on this site. Id you still need help then share the models and service source.

 [HttpPost]
 [AutoValidateAntiforgeryToken]
 public ActionResult Update(CustomerInformation model)
 {
     if (ModelState.IsValid)
     {
         //save
         var UpdateRecord = customerServices.Update(model);
         if (UpdateRecord)
         {
             return RedirectToAction("Details");
         }
     }
     return View(model);
 }


0 Votes 0 ·

Thank you very much for your reply.
The issue is that it never hits my breakpoint when I pass the viewmodel to the method. But it does work and hit the breakpoint if I don't pass anything or pass "IFormCollection" to the method.

For now I just wrote code for the Model state being valid. Once this work then I will add the code to handle the invalid state as well.

If anyone can help me understand why the application crashes when I pass the viewmodel to the controller that would be of massive help.

0 Votes 0 ·

You've defined the View as @model Customer.Models.CustomerInformationDetails and the Action as public ActionResult Update(CustomerInformation model). These models do not match.

In MVC the model binder matches the input names from the View with the Action's input parameter property names. IFormCollection works because it is a generic container. You did not share the two models so we cannot verify the property names. Most likely, not following MVC model binding rules is the issue.

Another troubleshooting tip is using the browser's dev tools (F12). Look for errors returned in the Network view.

0 Votes 0 ·
Show more comments

It looks to me that you are using the EF persistence model calling it a viewmodel, and it's not a viewmodel. A viewmodel is strong typed to a given view. You map between a viewmodel and the persistence model, and the VM is sent into the view. The VM is mapped back to the persistence model for data persistence.

https://deviq.com/terms/kinds-of-models

https://www.dotnettricks.com/learn/mvc/understanding-viewmodel-in-aspnet-mvc

The calling of the service and mapping between the VM and PM should be happening with objects in the Models folder all controller logic should be kept thin.

The usage of the Models folder is explained in the link.

https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

The example solution out on Github shows the usage of VM = viewmodel and DM = domain model objects in the Models folder.

https://github.com/darnold924/PublishingCompany


HTH

0 Votes 0 ·

Thank you so much for your reply. I checked all the links that you are referencing to and it seems that I'm doing exactly what they have seen in their examples.

I'm using .Net Core and I have my models in the models folder and then Services to interact with the View and Controller.
The thing that's not working is when I pass my model class as a parameter onpost event in the controller.

0 Votes 0 ·

You say it's crashing. Are you getting some kind of exception or HTTP status code?



















0 Votes 0 ·
Show more comments

0 Answers