【问题标题】:Partial server side validation for complex property复杂属性的部分服务器端验证
【发布时间】:2021-03-07 08:50:33
【问题描述】:

在 ASP.NET Core 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; }
}

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

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

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

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core modelstate server-side-validation


    【解决方案1】:

    ModelState.Remove("ContactInfo");

    似乎ModelState不包含“ContactInfo”键,所以它不起作用。如果你想在子类中禁用验证,如你所料,你需要删除其中的所有属性,例如:

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

    但它似乎重复且难以维护,尤其是因为我的类包含更多属性。

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

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

    【讨论】:

    • 嗨@petra,如果它有帮助,你可以接受它作为答案,谢谢:)。
    • 这是我需要的。抱歉,我花了一些时间才接受,我想好好测试一下。
    【解决方案2】:

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

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

    【讨论】:

    • 感谢您的回答,但我不明白这对我有什么帮助...但是,我尝试将该属性添加到属性中,但出现错误;我应该添加一些命名空间引用吗?而且我不知道“如果你有数组”是什么意思?
    • 您需要查看控制器中的响应字符串以查看响应的样子。如果响应是 xml,则根标签是 Person。一个复杂的属性可以有子类(xml 子类),这些类可以是数组。在没有看到响应的情况下不确定您的复杂属性是什么..
    猜你喜欢
    • 2011-11-06
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多