我正在追踪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个字段,其中包含一些复杂的业务规则和交互,在两个页面上都是相同的,除了需要哪些字段。
答案 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美分。