EmailAddressAttribute without being required

血红的双手。 提交于 2019-12-10 12:39:18

问题


I have a [EmailAddress] DataAnnotation from .net 4.5 on a model property, which returns a 'The Email field is not a valid e-mail address.' error during validation, when the Email property is empty.

While this is technically true, I would have expected this empty value to only be caught with a [Required] annotation.

Is there any parameter I'm missing which can be passed to the [EmailAddress] annotation to allow empty strings to validate, or do I have to fall back to using a custom validator regular expression?


回答1:


There is no such parameter for EmailAddressAttribute. The validation code for this attibute is following:

if (value == null)
{
    return true;
}
string input = value as string;
return ((input != null) && (_regex.Match(input).Length > 0));

And the regex is defined as (there will be no match for empty string):

_regex = new Regex(@"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$", RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);

To achieve your goal you can create your can inherit from DataTypeAttribute override IsValid method, so it will return true for empty or null strings and use instance of EmailAddressAttribute. This should be something like this:

public override bool IsValid(object value)
{
    if (value == null)
    {
        return true;
    }
    string input = value as string;
    var emailAddressAttribute = new EmailAddressAttribute();

    return (input != null) && (string.IsNullOrEmpty(input) || emailAddressAttribute.IsValid(input));
}



回答2:


Other way is to just call API differently. For JSON ask caller to provide "Email": null or don't include this property in the body. For XML ask caller who is providing empty element <Email></Email> to remove this element from message body if email is not available.

If JSON property is null or not present or XML element not present, the field in your model becomes null and thus won't throw validation error because is just not present unless you have [Required] added. This way you drive required or not.

I do understand in some instances "lazy" or unable caller may want to always send same body with empty value, especially for XML. "I'm sending this <Email></Email> because my customer didn't provide me the email"



来源:https://stackoverflow.com/questions/16098903/emailaddressattribute-without-being-required

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