Make MVC class property/class required conditionally

吃可爱长大的小学妹 提交于 2019-12-11 10:56:45

问题


I have an Address class that is used for both a MailingAddress and BillingAddress property in my Model. I want the MailingAddress to be required, but not the BillingAddress, but am not seeing a way to do this with DataAnnotations.

If I were able to set the [Required] attribute on the MailingAddress property and somehow define the logic for how the Address class is supposed to handle the required logic, I feel like that would be a simple solution.

Any ideas?


回答1:


If your question is how to use the Required attribute in your own logic, the answer is by use of reflection. Forgive me if that is not your question.

Get all properties from the type in question, then see if it is decorated with a RequiredAttribute or not.

class ParentClass
{
      [Required]
      public Address MailingAddress { get; set; }

      public Address BillingAddress { get; set; }
}

(...)

Type t = typeof(ParentClass);

foreach (PropertyInfo p in t.GetProperties())
{
    Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
    if (a != null)
    {
          // The property is required, apply your logic
    }
    else
    {
          // The property is not required, apply your logic
    }
}

Edit: Fixed a typo in code

Edit 2: Extended code example




回答2:


This is just an odd quirk which popped into my head:

A simple solution might be to subclass Address to OptionalAddress.

I don't think the Required attributes would be inherited to the child class.

[AttributeUsage (Inherited = False)] also comes to mind if needed.

A more MVCish solution might be to implement a custom model binder (completely untested):

public override object BindModel(ControllerContext controllerContext,
    ModelBindingContext bindingContext)
        {
            var address = base.BindModel(controllerContext, bindingContext) as Address;
            if (bindingContext.ModelName.EndsWith("BillingAddress"))
            {
                foreach (PropertyInfo p in address.GetType().GetProperties())
                {
                Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
                if (a != null 
                    && propertyInfo.GetValue(address, null) == null 
                    && bindingContext.ModelState[bindingContext.ModelName 
                       + "." + p.Name].Errors.Count == 1)
                {
                    bindingContext.ModelState[bindingContext.ModelName + "." + p.Name].Errors.Clear();
                }
            }
            return address;
        }



回答3:


Many options available at this previously asked question:

ASP.NET MVC Conditional validation

Do you need this validation done on the client side or not?

IValidateableObject will be used in conjunction with any of your existing attributes and can provide for the additional custom validation.



来源:https://stackoverflow.com/questions/7264840/make-mvc-class-property-class-required-conditionally

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!