复杂 属性 的部分服务器端验证
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);
}
在 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);
}