Question

I have property in my PersonDTO class:

[EmailAddress]
public string Email { get; set; }

It works fine, except I want to allow empty strings as values for my model, if I send JSON from client side:

{ Email: "" }

I got 400 bad request response and

{"$id":"1","Message":"The Email field is not a valid e-mail address."}

However, it allows omitting email value:

{ FirstName: "First", LastName: 'Last' }

I also tried:

[DataType(DataType.EmailAddress, ErrorMessage = "Email address is not valid")]

but it does not work.

As far as I understood, Data Annotations Extensions pack does not allow empty string either.

Thus, I wonder if there is a way to customize the standard EmailAddressAttribute to allow empty strings so I do not have to write custom validation attribute.

Was it helpful?

Solution

You have two options:

  1. Convert string.Empty to null on the Email field. Many times that is perfectly acceptable. You can make this work globally, or by simply making your setter convert string.Empty to null on the email field.
  2. Write a custom EmailAddress attribute, since EmailAddressAttribute is sealed you can wrap it and write your own forwarding IsValid method.

Sample:

bool IsValid(object value)
{
    if (value == string.Empty)
    {
        return true;
    }
    else
    {
        return _wrappedAttribute.IsValid(value);
    }
}

Expansion on option 1 (from Web Api not converting json empty strings values to null)

Add this converter:

public class EmptyToNullConverter : JsonConverter
{
    private JsonSerializer _stringSerializer = new JsonSerializer();

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(string);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
                                    object existingValue, JsonSerializer serializer)
    {
        string value = _stringSerializer.Deserialize<string>(reader);

        if (string.IsNullOrEmpty(value))
        {
            value = null;
        }

        return value;
    }

    public override void WriteJson(JsonWriter writer, object value, 
                                   JsonSerializer serializer)
    {
        _stringSerializer.Serialize(writer, value);
    }
}

and use on the property:

[JsonConverter(typeof(EmptyToNullConverter))]
public string EmailAddress {get; set; }

or globally in WebApiConfig.cs:

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
    new EmptyToNullConverter());

OTHER TIPS

It's Easy. Do This. Bye

private string _Email;
[EmailAddress(ErrorMessage = "Ingrese un formato de email válido")]
public string Email { get { return _Email; } set { _Email = string.IsNullOrWhiteSpace(value) ? null : value; } }

I used the suggestion from Yishai Galatzer to make a new ValidationAttribute called EmailAddressThatAllowsBlanks:

namespace System.ComponentModel.DataAnnotations
{
    public class EmailAddressThatAllowsBlanks : ValidationAttribute
    {
        public const string DefaultErrorMessage = "{0} must be a valid email address";
        private EmailAddressAttribute _validator = new EmailAddressAttribute();

        public EmailAddressThatAllowsBlanks() : base(DefaultErrorMessage)
        {

        }

        public override bool IsValid(object value)
        {
            if (string.IsNullOrEmpty(value.ToString()))
                return true;

            return _validator.IsValid(value.ToString());
        }
    }
}

Set TargetNullValue property of the binding to an empty string.

TargetNullValue=''
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top