I wrote an application using ASP.NET MVC 5 framework. I am using a two way binding between the views and the ViewModels.
Since I am using two way binding, I get the benefit of client and server side validation which is cool. However, when I send a POST
request to the server, and the request handler throws an exception, I want to redirect the user to the GET
method.
When the redirect happens, I want to save the model state so that the page looks the same when I display the errors. I am able to save the state model and the errors using ActionFilters
and TempData
via this approach. However, when the request is redirected, from POST
to GET
the model state is saved as System.Web.Mvc.ModelStateDictionary
object which is a key/value pair with all the user input that came from the POST
request.
In order to present the page correctly to the end user, I need to bind the data in System.Web.Mvc.ModelStateDictionary
to my own presentation model.
How can I bind the System.Web.Mvc.ModelStateDictionary
object to my presentation object?
Here is how my code looks like
[ImportModelStateFromTempData]
public ActionResult show(int id)
{
var prsenter = new UserProfileDetailsPresenter(id);
ModelStateDictionary tmp = TempData["Support.ModelStateTempDataTransfer"];
if(tmp != null)
{
// Some how map tmp to prsenter
}
return View(prsenter);
}
[HttpPost]
[ValidateAntiForgeryToken]
[ExportModelStateToTempData]
public ActionResult Update(int id, DetailsPresenter model)
{
try
{
if (ModelState.IsValid)
{
var updater = new UpdateAddressServiceProvider(CurrentUser);
updater.Handle(model.General);
}
}
catch (Exception exception)
{
ModelState.AddModelError("error", exception.Message);
} finally
{
return new RedirectResult(Url.Action("Show", new { Id = id }) + "#General");
}
}
If there's an error, don't redirect, just return the View.
[HttpPost]
[ValidateAntiForgeryToken]
[ExportModelStateToTempData]
public ActionResult Update(int id, DetailsPresenter model)
{
try
{
if (ModelState.IsValid)
{
var updater = new UpdateAddressServiceProvider(CurrentUser);
updater.Handle(model.General);
}
return new RedirectResult(Url.Action("Show", new { Id = id }) + "#General");
}
catch (Exception exception)
{
ModelState.AddModelError("error", exception.Message);
// Return the named view directly, and pass in the model as it stands.
return View("Show", model);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With