复杂 属性 的部分服务器端验证

Partial server side validation for complex property

在 ASP.NET 核心 MVC 应用程序中,我需要跳过控制器操作中某些复杂 属性 的模型验证。
假设我有以下模型结构:

public class Person
{
    public int PersonID { get; set; }
    public PersonalInfo PersonalInfo { get; set; }
    public ContactInfo ContactInfo { get; set; }

    public Person()
    {
        PersonalInfo = new PersonalInfo();
        ContactInfo = new ContactInfo();
    }
}

public class PersonalInfo 
{
        [Required(ErrorMessage = "First name is required")]
        public string FirstName { get; set; }

        [Required(ErrorMessage = "Last name is required")]
        public string LastName { get; set; }
}

public class ContactInfo 
{
        [Required(ErrorMessage = "Phone is required")]
        public string Phone { get; set; }

        [Required(ErrorMessage = "Email is required")]
        public string Email{ get; set; }
}

在 post 操作中,我想跳过对 ContactInfo 的验证,尽管它是模型的一部分并且已提交。像这样:

[HttpPost]
public ActionResult SavePerson(Person model)
{
    ModelState.Remove("ContactInfo");
    if (ModelState.IsValid)
    { 
        (...)
    }
}

如果 ContactInfo 很简单(“标量”是正确的术语吗?),这会起作用 属性。
我知道你们中的一些人会建议我使用单独的视图模型,但我认为它不适用于这种情况(我正在尝试创建一个包含多个步骤的表单,并且所有数据都必须在表单上以便提交以便在步骤之间保留...)
另外,我想我可以对 ContactInfo class 的每个 属性 使用 ModelState.Remove,但它似乎重复且难以维护,特别是因为我的 classes 包含更多属性。

如果您有数组,请尝试以下操作。如果不将 XmlElement 与数组 Xml 一起使用,序列化需要两个 Xml 标签。使用 XmlElement 只需要一个标签。 :

    [XmlElement()]
    public List<PersonalInfo> PersonalInfo { get; set; }
    [XmlElement()]
    public List<ContactInfo> ContactInfo { get; set; }

ModelState.Remove("ContactInfo");

似乎 ModelState 不包含“ContactInfo”键,因此它不起作用。如果你想在child class中禁用validation,如你所料,你需要移除其中的所有属性,如:

ModelState.Remove("ContactInfo.Phone");
ModelState.Remove("ContactInfo.Email");

but it seems repetitive and difficult to maintain, especially because my classes contain much more properties.

属性多的时候确实是重复的,但是可以使用反射来简化。

foreach (var property in model.ContactInfo.GetType().GetProperties())
{
    ModelState.Remove("ContactInfo." + property.Name);
}