Allow empty strings for fields marked with PhoneAttribute or UrlAttribute
Solution 1
Validation attributes like [Phone]
and [EmailAddress]
will check any non-null string values. Because the string
type is inherently nullable, empty strings passed to the ModelBinder are read as null
, which passes the validation check.
When you add the [Required]
attribute, the string becomes effectively non-nullable. (If using Code First, EF will script a non-nullable database column.) The ModelBinder will now interpret a blank value as String.Empty
- which will fail the attribute validation check.
So there is no way to allow empty strings with validation attributes, but you can allow null strings. All you need to do is remove the [Required]
attribute. Blank values will be null
and non-blank values will be validated.
In my case, I am importing records from a CSV file, and had this problem because I was skipping the normal ModelBinder. If you are doing something unusual like this, be sure to include a manual check before saving to your data model:
Email = (record.Email == String.Empty) ? null : record.Email
Solution 2
Use following two data annotations:
[Required(AllowEmptyStrings = true)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
Solution 3
I did something similar below.
[JsonProperty("phone")]
[NullablePhone]
public string Phone { get; set; }
/// <summary>
/// Validation attribute for phone numbers.
/// </summary>
/// <seealso cref="ValidationAttribute" />
public class NullablePhoneAttribute : ValidationAttribute
{
/// <summary>
/// Returns true if phone is empty or valid.
/// </summary>
/// <param name="value">The value of the object to validate.</param>
/// <returns>
/// <see langword="true" /> if the specified value is valid; otherwise, <see langword="false" />.
/// </returns>
public override bool IsValid(object value)
{
if (value == null)
{
return true;
}
if (string.IsNullOrEmpty(value.ToString()))
{
return true;
}
PhoneAttribute phone = new PhoneAttribute();
return phone.IsValid(value);
}
}
Nu-hin
Updated on June 25, 2021Comments
-
Nu-hin almost 3 years
I'm using CodeFirst Entitty framework 5. I have a class representing a user.
public class User { [Key] public int UserId { get; set; } [Url] [DataType(DataType.Url)] [Required(AllowEmptyStrings= true)] public string WebSite { get; set; } [Phone] [DataType(DataType.PhoneNumber)] [Required(AllowEmptyStrings = true)] public string Phone { get; set; } [Phone] [DataType(DataType.PhoneNumber)] [Required(AllowEmptyStrings = true)] public string Fax { get; set; } }
I like the validation mechanics for
Phone
andUrl
attributes a lot, but unfortunately validation fails when fields marked with these attributes are empty strings which I actually want to allow.[Required(AllowEmptyStrings = true)]
doesn't seem to work withPhone
orUrl
attributes. The same seems to apply to some other DataAnnotations attributes likeEmailAddress
.Is there a way to allow empty strings for fields marked with such attributes?
-
Nu-hin over 10 yearsI wasn't using Model Binder. I was writing data importer and the source data contains empty emails and phones. I guess I should just convert empty strings from source to nulls then. Thanks for the explanation!
-
Gerald Davis almost 9 years@Nu-hin. Your DBA will thank you in the future if you get in a habbit of cleaning up ambiguous pointless values like empty strings and replacing them with null. Null is undefined or unknown. A empty string phone number is undefined or unknown. Always fun to do work on a db years later and find a mix of null, empty strings, whitespace strings, and the always helpful "NO PHONE NUMBER" in the phone number field.
-
Ian Griffiths over 8 yearsThis seems pretty unhelpful. Yes in some situations, the absence of a value means "not known", but "Definitely empty" means something quite different from "Not known". So there are cases where a empty string is not a "pointless value".
-
daniel.caspers over 7 yearsThis did not work for me with the DomainAttribute but did work with the EmailAddressAttribute!
-
Marek Bar over 7 yearsWorks very well but I wonder why visual has generated in my case [Required][StringLength(10)] if I have not null, nvarchar(10)
-
HGMamaci about 7 yearsRemoving this "[DisplayFormat(ConvertEmptyStringToNull = false)]" has worked for me. Thank you
-
TheKido about 7 yearsWorks for me on Core. Thanks!
-
Mord Zuber over 6 yearsThis does not seem to work anymore with
System.ComponentModel.DataAnnotations.EmailAddressAttribute
as empty strings are failing validation, even though the field is not required -
Neil Laslett over 6 years@MordZuber Interesting. Two options: either
EmailAddressAttribute
has been updated to validatenull
strings or the ModelBinder is setting your blank incoming value tostring.Empty
instead ofnull
. Can you remove the validation and check the actual value set by ModelBinder? -
Mord Zuber over 6 yearsMy case was string.Empty being sent over the wire. Since the validator only checks for null, it was failing, so I just wrote a new wrapper attribute
-
Neil Laslett over 6 years
EmailAddressAttribute
definitely still passes null values. referencesource.microsoft.com/… I wonder why it was setting it to empty? -
Neil Laslett over 6 yearsGood reference: stackoverflow.com/questions/3641723/…
-
Mário Meyrelles almost 3 yearsIndeed. Works on Core API 3.1 also.