Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Can I Use Data Annotations Attribute Classes to Fail Empty Strings in Forms?

I was trying to require a text input field in a form, which implies that there needs to be something in the form. However, adding a [Required] tag to my model wasn't working. Specifically, look at the User Name property:

public class ColumnWidthMetaData {
    [DisplayName("Column Name")]
    [Required]
    public string ColName { get; set; }

    [DisplayName("Primary Key")]
    public int pKey { get; set; }

    [DisplayName("User Name")]
    [Required]
    public string UserName { get; set; }

    [DisplayName("Column Width")]
    [Required]
    public int Width { get; set; }
}

This allows empty strings to get past model validation and eventually a database error is thrown when it attempts to insert a NULL value for User Name.

How can I change these attributes so they do what they seem like they should do?

like image 510
DCShannon Avatar asked May 29 '14 17:05

DCShannon


People also ask

What is data annotation attribute?

We'll use the following Data Annotation attributes: Required – Indicates that the property is a required field. DisplayName – Defines the text to use on form fields and validation messages. StringLength – Defines a maximum length for a string field. Range – Gives a maximum and minimum value for a numeric field.

What is data annotation validator attributes in MVC?

Data annotation attributes are attached to the properties of the model class and enforce some validation criteria. They are capable of performing validation on the server side as well as on the client side. This article discusses the basics of using these attributes in an ASP.NET MVC application.


3 Answers

After a lot of Googling and looking on Stackoverflow, I had nothing.

I went to MSDN and looked at the System.ComponentModel.DataAnnotations Namespace.

There I looked more closely at the Required attribute, and noticed the AllowEmptyStrings property. Setting this to false tells the attribute not to allow any empty strings, which I would have assumed was the default behavior, seeing as how the point of Required is to require that something be entered, and an empty string indicates that nothing was entered.

This doesn't solve the problem though, as by default empty strings are coerced to null, which are not empty strings, and are therefore allowed. Once again this is absurd, as Required is supposed to test if something was entered, and null indicates nothing was entered. However, the AllowEmptyStrings page has a link to DisplayFormAttribute's Property ConvertEmptyStringsToNull. If you set this to false, then empty strings will remain empty strings, and then the required tag will not allow them.

So, here's the fix:

public class ColumnWidthMetaData {
    [DisplayName("Column Name")]
    [Required(AllowEmptyStrings=false)]
    [DisplayFormat(ConvertEmptyStringToNull=false)]
    public string ColName { get; set; }

    [DisplayName("Primary Key")]
    public int pKey { get; set; }

    [DisplayName("User Name")]
    [Required(AllowEmptyStrings=false)]
    [DisplayFormat(ConvertEmptyStringToNull=false)]
    public string UserName { get; set; }

    [DisplayName("Column Width")]
    [Required]
    public int Width { get; set; }
}    
like image 88
DCShannon Avatar answered Oct 02 '22 15:10

DCShannon


I'd implement a new validation attribute like this and apply it to my model.

public class RequiredNotEmptyAttribute : RequiredAttribute
{
    public override bool IsValid(object value)
    {
        if(value is string) return !String.IsNullOrEmpty((string)value);

        return base.IsValid(value);
    }
}

This will only work on the server side (client side will still only check for null).

like image 29
Nathan A Avatar answered Oct 02 '22 14:10

Nathan A


You could use [MinLength(1)]. See msdn docs here.

like image 34
firefox1986 Avatar answered Oct 02 '22 13:10

firefox1986