检索模型元数据的HtmlHelper方法中的行为不一致

时间:2011-07-18 19:23:34

标签: c# asp.net-mvc-3 modelmetadata

我正在追踪MVC3中的意外行为,与如何获取模型元数据有关。

我之前曾与我的一位开发人员讨论过使用相同的EditorTemplate来处理在系统的两个不同区域收集的数据。除[Required]属性外,数据字段几乎相同。在一个页面中,某些字段是必需的,而在另一个页面中则不是。从理论上讲,这可以通过使用基本模型来完成,该模型在每个字段上具有公共属性,并继承这些模型,覆盖属性并添加其他验证属性。例如:

class BaseModel
{
    [Display(Name=”My Label”)]
    public virtual string MyLabel { get; set ;}
}

class RequiredModel : BaseModel
{
    [Required]
    public override string MyLabel { get; set ;}
}

然后View可以强类型化为BaseModel,并且视图中对@ Html.EditorFor(m => m.MyLabel)的调用应该选择正确的属性,具体取决于模型的实际实例是否为BaseModel或RequiredModel。

这就是理论。

事实上,如果您使用“旧”HTML帮助程序,例如@ Html.TextBox(“MyLabel”)。那些调用ModelMetadata.FromStringExpression(field),如果具体模型实例是RequiredModel,它会正确地从RequiredModel获取元数据。较新的辅助方法调用ModelMetadata.FromLambdaExpression(expression),它不能正确地从正确的具体实例中获取元数据。

这是MVC中的错误吗?故意行为?是否有解决方法或解决此问题的更好方法?

这当然是一个简单的例子,我们正在处理的实际代码有大约20个字段,其中包含一些复杂的业务规则和交互,在两个页面上都是相同的,除了需要哪些字段。

1 个答案:

答案 0 :(得分:0)

  

这就是理论。

不,那不是理论。至少不是我的。

我的理论是为每个视图使用单独的视图模型,因为视图的要求不同。所以你会有这个:

public class UpdateViewModel
{
    [Display(Name = "My Label")]
    public string MyLabel { get; set ;}
}

public class CreateViewModel
{
    [Display(Name = "My Label")]
    [Required]
    public string MyLabel { get; set ;}
}

就个人而言,这就是我要做的。我会完全牺牲DRY来设计视图模型,因为我的视图要求经常变化,我想要完全控制。

显然在实践中,我甚至不愿意使用声明性DataAnnotations属性进行验证。他们限制我。我使用FluentValidation.NET以非常优雅的方式处理像你这样的问题(通过简单地为同一个视图模型定义两个不同的验证器 - 如果你决定违反我的理论并在不同的视图中使用相同的视图模型)。 / p>

现在可以随心所欲地回答我的回答。我刚刚给了我2美分。