因此我们使用DataAnnotations来实现ASP.NET MVC表单的输入验证。如果我们重新开始,我会考虑流利验证,但我们现在做的太过分了。
所以这个项目要求我们建立很多形式。随着我们的进步,我们已经确定了在表单中重复的输入组。一个例子可能是一组表示地址的输入。
然后我们通过为其创建_AddressEntry
部分视图以及相关的视图模型AddressViewModel
,将地址输入转换为可重复使用的模块。然后,父表单的视图模型如下所示:
public class SubmitEnquiryViewModel
{
public AddressViewModel Address { get; set; }
public string Enquiry { get; set; }
...
}
在_SubmitEnquiry
视图中,我们使用_AddressEntry
插入EditorFor()
部分视图。
这一点工作正常,直到我们意识到地址输入的不同实例具有不同的验证要求 - 装饰AddressViewModel
的验证属性并不总是适用。为了解决这个问题,我们定义了IAddressViewModel
:
public interface IAddressViewModel
{
string LineOne { get; set; }
string LineTwo { get; set; }
...
}
然后为验证规范的所有不同排列定义此接口的具体实现 - 例如AddressViewModel
(默认验证),AddressNoValidationViewModel
等。
然后将_AddressEntry
部分视图绑定到IAddressViewModel
,并为父视图模型的Address属性选择适当的具体实现。
这种方法的主要缺点是我们可能最终会得到相当多的视图模型,这些视图模型仅因应用于它们的验证属性而不同。尽管可重用模块的数量预计相对较小,但这被认为是可以接受的。
之前还有其他人遇到过这个挑战吗?你想出了什么解决方案?您对上述解决方案有何看法?
答案 0 :(得分:1)
您可能需要查看MetadataTypeAttribute。
基类:
public abstract class AddressDetailsBase
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public int PostalCode { get; set;}
}
验证(我使用接口以便不会意外地实例化):
public interface IUserAddressDetailsValidation
{
[required]
string Line1 { get; set; }
[required]
string Line2 { get; set; }
[required]
string City { get; set; }
[required]
string State { get; set; }
[required]
int PostalCode { get; set;}
}
查看型号类型:
[MetadataType(typeof(IUserAddressDetailsValidation))]
public class UserAddressDetails : AddressDetailsBase { }
答案 1 :(得分:0)
数据注释适用于非常简单的场景和原型项目。 正如您所看到的,您已经在与注释作斗争,这些注释不适合在不同的环境中工作。
只需在控制器操作中使用普通的ModelState.AddModelError,并在控制器中构建自定义验证逻辑。
ModelState.AddModelError("Prop", "Your custom 'validation failed' message.");
在进行自定义验证之前,您仍然可以评估ModelState.IsValid
,因此您仍然可以将DataAnnotations用于一些代码重用的简单案例。