Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow empty strings for fields marked with PhoneAttribute or UrlAttribute

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 and Url 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 with Phone or Url attributes. The same seems to apply to some other DataAnnotations attributes like EmailAddress.

Is there a way to allow empty strings for fields marked with such attributes?

like image 338
Nu-hin Avatar asked Oct 02 '13 11:10

Nu-hin


3 Answers

Use following two data annotations:

[Required(AllowEmptyStrings = true)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
like image 182
user5791468 Avatar answered Nov 05 '22 06:11

user5791468


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
like image 39
Neil Laslett Avatar answered Nov 05 '22 05:11

Neil Laslett


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);
    }

}
like image 1
Teoman shipahi Avatar answered Nov 05 '22 06:11

Teoman shipahi