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
,除非完成所有必需的属性,否则验证将失败。