Asp.net mvc重建ViewModel的最佳做法是什么?

pjo*_*obs 6 asp.net-mvc

在POST时,如果验证失败并且在将ViewModel发送回具有模型状态错误的同一视图之前,您是否为所有SelectLists,ReadOnly字段等重建ViewModel?现在我有单独的Fill First Time方法(用于GET Edit-Method)/从域对象重建ViewModel,最好的做法是什么,所以我可以干,也不必在每次添加新的readonly属性时更改两种方法到ViewModel?

我的解决方案:遵循这种模式

此处建议遵循以下模式:https: //stackoverflow.com/a/2775656/57132在IModelBuilder实现中

Build(..)
{  
   var viewModel = new ViewModel();     
   // and Fill all Non-ReadOnly fields
   ...
   ...
   call CompleteViewModel(viewModel)     
}  

CompleteViewModel(ViewModel viewModel)
{
  //Fill all ReadOnly & SelectLists
  ...
}
Run Code Online (Sandbox Code Playgroud)

我使用此解决方案的原因是因为我不希望将内容存储在服务器上以跨HTTP请求进行检索

Luk*_*Led 7

我没有重建它,因为我没有留在POST.我遵循POST-REDIRECT-GET模式,所以如果我使用POST HTTP方法发布到/ User/Edit/1,我会被重定向到/ User/Edit/1 uasing GET.

ModelState转移到TempData后续重定向 - 获取并在GET呼叫时可用.在GET调用中,View模型构建在一个地方.例:

    [HttpPost]
    [ExportModelStateToTempData]
    public ActionResult Edit(int id, SomeVM postedModel)
    {
        if (ModelState.IsValid) {
            //do something with postedModel and then go back to list
            return RedirectToAction(ControllerActions.List);
        }

        //return back to edit, because there was an error
        return RedirectToAction(ControllerActions.Edit, new { id });
    }

    [ImportModelStateFromTempData]
    public ActionResult Edit(int id)
    {
        var model = //create model here
        return View(ControllerActions.Edit, model);
    }
Run Code Online (Sandbox Code Playgroud)

这是属性导入/导出的代码ModelState:

public abstract class ModelStateTempDataTransferAttribute : ActionFilterAttribute
{
    protected static readonly string Key = typeof(ModelStateTempDataTransferAttribute).FullName;
}

public class ExportModelStateToTempDataAttribute : ModelStateTempDataTransferAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //Only export when ModelState is not valid
        if (!filterContext.Controller.ViewData.ModelState.IsValid)
        {
            //Export if we are redirecting
            if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
            {
                filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
            }
        }

        base.OnActionExecuted(filterContext);
    }
}

public class ImportModelStateFromTempDataAttribute : ModelStateTempDataTransferAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        ModelStateDictionary modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;

        if (modelState != null)
        {
            //Only Import if we are viewing
            if (filterContext.Result is ViewResult)
            {
                filterContext.Controller.ViewData.ModelState.Merge(modelState);
            }
            else
            {
                //Otherwise remove it.
                filterContext.Controller.TempData.Remove(Key);
            }
        }

        base.OnActionExecuted(filterContext);
    }
}
Run Code Online (Sandbox Code Playgroud)