MVC ViewModel具有可编辑和只读数据的最佳实践

时间:2012-12-18 07:43:31

标签: asp.net-mvc-4 asp.net-mvc-viewmodel

我想知道在同一个viewModel中处理可编辑/只读字段的最佳做法是什么。 对于更大的ViewModel,我面临这个问题,但我们假设我有一个非常简单的ViewModel:

public class BaseListViewModel
{
    public int Id { get; set; }
    public bool IsCheckedForAction { get; set; }
    public string DisplayName { get; set; }
}

我的偏见:

@model Wims.Website.ViewModels.Shared.BaseModelListViewModel
@using Wims.Website.Classes.Helpers.ExtentionMethods
<div class="dataDetail">
        <div>
            <div class="float-left">
                @Html.CheckBoxFor(model => model.IsCheckedForAction)
            </div>

            <div class="float-left">
                @Html.LabelFor(model => model.IsCheckedForAction, Model.DisplayName)


                @Html.GenerateSecureDataControls(w => w.Id)
            </div>
        </div>
    </div>
<div style="clear: both"></div>

显然,当我发布我的数据时,不会填充DisplayName。 假设某些验证失败,我只返回收到的DisplayName将丢失的数据。

    [HttpPost]

public ActionResult Edit(BaseListViewModel stuff)
{
    if (ModelState.IsValid)
    {
        ...
        return View("Index");
    }
    return View(stuff);
}

我知道有几种方法可以解决这个问题:

1)添加

  @Html.HiddenFor(model => model.DisplayName)
在视图中

,如果它只是1个字段就可以了,但是,如果我确实只有10个显示字段会怎么样?

2)在[HttpPost]中重新查询数据if(!Model.isValid)。

3)我想我可以在TempData中缓存它吗?

最好的方法是什么? 谢谢!

编辑:我试图避免在验证失败时重新查询数据

2 个答案:

答案 0 :(得分:3)

我使用PRG模式。由于您只在GET操作中构建ViewModel,因此更干。如果验证失败,则重定向到GET并从tempdata中获取模型状态。

本文中的属性http://www.jefclaes.be/2012/06/persisting-model-state-when-using-prg.html或MVC Contrib https://github.com/mvccontrib/MvcContrib/blob/master/src/MVCContrib/Filters/ModelStateToTempDataAttribute.cs使得在POST和GET之间传递Modelstate变得容易

答案 1 :(得分:0)

POST操作应该执行与GET操作相同的viewmodel初始化。您可以将初始化代码移动到控制器中的公共私有函数中。这样做的原因是,如果由于对同一数据的某些并发更改而导致验证失败,则验证错误将与新数据一起显示给用户。如果视图允许,您也可以使用PRG模式。