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

本文关键字:不一致 元数据 模型 方法 检索 HtmlHelper | 更新日期: 2023-09-27 18:02:47

我正在追踪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 ;}
}

然后视图可以强类型为BaseModel,并且调用视图中的@Html.EditorFor(m=>m.MyLabel)应该拾取正确的属性,这取决于模型的实际实例是BaseModel还是RequiredModel。

理论就是这样。

事实上,如果你使用"旧的"HTML帮助器,例如@Html.TextBox(" MyLabel "),它会工作得很好。它们调用ModelMetadata.FromStringExpression(field),如果具体的模型实例是RequiredModel,它将正确地从RequiredModel获取元数据。新的辅助方法调用ModelMetadata.FromLambdaExpression(expression),它不能正确地从正确的具体实例中获取元数据。

这是一个错误在MVC?有意的行为?有没有解决这个问题的方法或者更好的方法?

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

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

理论就是这样。

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

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

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。它以一种相当优雅的方式解决了像你这样的问题(通过简单地为相同的视图模型定义两个不同的验证器-以防你决定违反我的理论并在不同的视图中使用相同的视图模型)。

现在请随意否决我的回答。我刚交了2美分。