如何使用 ASP.NET MVC 将数据从 ModelStateDictionary 手动绑定到表示模型?

How can I manually bind data from a ModelStateDictionary to a presentation model with ASP.NET MVC?

我使用 ASP.NET MVC 5 框架编写了一个应用程序。我在视图和 ViewModel 之间使用双向绑定。

因为我使用的是双向绑定,所以我得到了客户端和服务器端验证的好处,这很酷。但是,当我向服务器发送 POST 请求并且请求处理程序抛出异常时,我想将用户重定向到 GET 方法。

发生重定向时,我想保存模型状态,以便显示错误时页面看起来相同。我可以使用 ActionFiltersTempData via this approach 保存状态模型和错误。然而,当请求被重定向时,从 POSTGET 模型状态被保存为 System.Web.Mvc.ModelStateDictionary 对象,它是一个 key/value 对,包含来自POST请求。

为了向最终用户正确呈现页面,我需要将 System.Web.Mvc.ModelStateDictionary 中的数据绑定到我自己的呈现模型。

如何将 System.Web.Mvc.ModelStateDictionary 对象绑定到我的演示对象?

这是我的代码的样子

[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");
    }
}

如果有错误,不要重定向,只是 return 视图。

[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);
    }
}