在ViewModel中重新设置“只读”数据的正确方法是什么?

时间:2013-12-06 19:30:04

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

我想在这里找出一个'最佳实践'并希望我不会太离谱。这是场景:

假设我们有两个动作。一个用于发送包含表单的Razor View。在这个表单上,有一个<select>加载了来自ViewModel的值(假设它是一个到期日期字段或其他东西)。还有供用户填写的字段,例如名称。

另一个Action接受视图的POST,模型作为参数:

[HttpPost]
[ActionName("MyForm")]
public virtual ActionResult MyForm(MyViewModel model) {
    // logic here
}

现在,如果模型存在某种问题(比方说,我们无法对其信用卡收费)。我们可以ModelState.AddModelError然后传回模型:

return View(model);

然而,这是最佳做法吗?我们的ViewModel中的属性怎么样,但我们没有从页面“返回”,例如我们的到期日期字段值。这些现在将为NULL,加载视图时会出现异常。

最佳做法是在发送回来之前始终“重新创建”视图模型(以某种方式接收它们输入的值,将它们覆盖到默认的viewmodel上?)或者我们应该有一些方法总是设置那些“只读”字段,并在两个操作中调用?

希望这个问题有道理。我不知道在视图上只调用“只读”的属性,而不是作为FORM POST的一部分传回。

感谢。

1 个答案:

答案 0 :(得分:1)

您拨打只读数据,some将其称为系统数据some 伙伴数据(使用更丰富的类和结构图),通常是referred to作为保湿

我通常接近它类似于this example(“一种总是设置这些字段的方法”)或者我将创建一个动作过滤器(OnActionExecuted),它会注入好友数据,具体取决于视图模型的类型。

例如:

public class ContactFormData
{
    // data which gets posted back
    public string Name {get; set;}
    public string CountryCode {get; set;}

    // buddy data
    public SelectList Countries {get; set;}
}

[HttpGet]
[ActionName("ContactForm")]
public virtual ActionResult ContactForm() {
    var m = new ContactFormData();
    return ShowContactForm(m);
}

[HttpPost]
[ActionName("ContactForm")]
public virtual ActionResult ContactForm(ContactFormData formdata) {
    if (ModelState.IsValid)
    {
         // logic & redirect
         return redirect;
    }
    return ShowContactForm(formdata);
}

private ActionResult ShowContactForm(ContactFormData formdata)
{
    formData.Countries = GetCountriesSelectListSomewhere();
    return View(m);
}