C# 对模型中的同一复杂属性类型应用不同的验证规则
到现在为止,这应该已经出现了一百万次了,但我似乎找不到任何我喜欢的固体 请考虑一下C# 对模型中的同一复杂属性类型应用不同的验证规则,c#,asp.net-mvc,asp.net-mvc-5,C#,Asp.net Mvc,Asp.net Mvc 5,到现在为止,这应该已经出现了一百万次了,但我似乎找不到任何我喜欢的固体 请考虑一下 public class Person { public string FirstName { get; set; } public string LastName { get; set; } public string Position { get; set; } } 在我的视图模型中出现两次 public class MyViewModel { public Person M
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Position { get; set; }
}
在我的视图模型中出现两次
public class MyViewModel
{
public Person MainContact { get; set; }
public Person AltContact { get; set; }
}
始终需要主触点。不需要其他联系人,但如果输入了任何内容,则应验证输入。如果我有两个不同的联系人类,它们的描述如下:
public class MainContact
{
[Required]
[StringLength(50)]
string FirstName { get; set; }
[Required]
[StringLength(50)]
string LastName { get; set; }
string Position { get; set; }
}
public class AltContact
{
[StringLength(50)]
string FirstName { get; set; }
[StringLength(50)]
string LastName { get; set; }
string Position { get; set; }
}
但是,我不希望有两个属性完全相同的联系人类
我希望一组验证应用于Person类的一个实例,另一组验证应用于同一Person类的不同实例。该解决方案还必须与客户端验证一起工作,同时打开不引人注目的js
更新1:为Person和Contact类添加了字符串位置
更新2:感谢大家的投入。考虑到时间限制和旧的UI需求,我最终拥有了两个独立的类。然而,我个人喜欢埃里克·芬肯布希(Erik Funkenbusch)在下面的评论中提出的替代方法。如果我将来遇到类似的情况,我将推动对象列表和“添加新Bla”按钮解决方案。我想这是一条路 由于Null属性答案似乎不适用于您,因此我建议使用以下模型:
public class MainContact: BaseContact
{
[Required]
[StringLength(50)]
public override string FirstName { get; set; }
[Required]
[StringLength(50)]
public override string LastName { get; set; }
}
public class BaseContact
{
[StringLength(50)]
public virtual string FirstName { get; set; }
[StringLength(50)]
public virtual string LastName { get; set; }
string Position { get; set; }
}
然后使主模型如下所示:
public class MyViewModel
{
[Required]
public MainContact MainContact { get; set; }
public BaseContact AltContact { get; set; }
}
您仍然需要有两个不同的模型,但您可以通过继承共享公共元素。由于Null属性答案似乎不适合您,因此我建议使用以下模型:
public class MainContact: BaseContact
{
[Required]
[StringLength(50)]
public override string FirstName { get; set; }
[Required]
[StringLength(50)]
public override string LastName { get; set; }
}
public class BaseContact
{
[StringLength(50)]
public virtual string FirstName { get; set; }
[StringLength(50)]
public virtual string LastName { get; set; }
string Position { get; set; }
}
然后使主模型如下所示:
public class MyViewModel
{
[Required]
public MainContact MainContact { get; set; }
public BaseContact AltContact { get; set; }
}
您仍然需要有两个不同的模型,但是您可以通过继承共享公共元素。为了这个问题,我可能将我的问题简化了。有了更新1,您的解决方案还能工作吗?是的,我们唯一做的就是在外部模型上选择altContact。如果altContact在模型上,那么它必须符合属性validates,如果没有,那么就没有验证。我刚刚试过你的例子,不引人注目的JS验证不起作用。此外,在本例中,我看不到将自定义错误消息连接到名字和姓氏字段的方法?它确实有效。我需要它与客户端不引人注目的JS验证一起工作。在复杂类型上粘贴[Required]在客户端没有任何作用,因为它希望查看和验证单个字段。即使我们忘记了客户端验证,它在服务器端提交时仍然不起作用。如果您没有为复杂类型输入任何值,则对象本身将获得一个新实例,其中单个字段为NULL。为了这个问题,我可能将问题过于简化了。有了更新1,您的解决方案还能工作吗?是的,我们唯一做的就是在外部模型上选择altContact。如果altContact在模型上,那么它必须符合属性validates,如果没有,那么就没有验证。我刚刚试过你的例子,不引人注目的JS验证不起作用。此外,在本例中,我看不到将自定义错误消息连接到名字和姓氏字段的方法?它确实有效。我需要它与客户端不引人注目的JS验证一起工作。在复杂类型上粘贴[Required]在客户端没有任何作用,因为它希望查看和验证单个字段。即使我们忘记了客户端验证,它在服务器端提交时仍然不起作用。如果您没有为复杂类型输入任何值,则对象本身将获得一个新实例,其中单个字段为NULL。您需要不同的视图模型,一个有属性,另一个没有属性。@StephenMuecke-为什么不呢?我能读到这方面的资料吗?谢谢。验证要么全是,要么什么都不是。一个选项是在中修改模型,包括(比如)一个
bool IsMandatory
,然后对属性使用[RequiredIfTrue(“IsMandatory”)]
或类似的条件属性(并在main contact
属性上设置IsMandatory=true
)但是,如果只填写了一个属性,则这并不要求需要AltContact
的所有属性。另一个选项是使用ajax动态添加AltContact
控件的“添加Alt Contact”按钮(并在成功回调中重新分析验证程序)。如果未添加AltContact
,则提交时它将为null
,并通过验证。如果您添加了它,那么AltContact
将不会为null
,除非所有必需的属性都已完成,否则验证将失败。简单的回答是您不能。您需要不同的视图模型,一个有属性,另一个没有属性。@StephenMuecke-为什么不呢?我能读到这方面的资料吗?谢谢。验证要么全是,要么什么都不是。一个选项是在中修改模型,包括(比如)一个bool IsMandatory
,然后对属性使用[RequiredIfTrue(“IsMandatory”)]
或类似的条件属性(并在main contact
属性上设置IsMandatory=true
)但是,如果只填写了一个属性,则这并不要求需要AltContact
的所有属性。另一个选项是使用ajax动态添加AltContact
控件的“添加Alt Contact”按钮(并在成功回调中重新分析验证程序)。如果未添加AltContact
,则提交时它将为null
,并通过验证。如果确实添加了它,则AltContact
将不会为null
,除非完成所有必需的属性,否则验证将失败。