You Have Chosen Poorly

Are you using Entity Framework and ASP.NET MVC along with client side validations? Are you trying to restrict the length of a string only to find that you client side validation isn’t working? Me too, and there is a solution!

MaxLength Attribute

In a recent project, we are using ASP.NET MVC 5 and Entity Framework 6 (EF for short). We are using Code First along with EF Migrations to update our underlying SQL database. We use Data Annotations throughout the project. A reoccurring pattern for many of our properties looked like this:

[Required]
[MaxLength(30)]
public string Name { get; set; }

Our goal here is to obviously require a Name value and to limit the length to 30 characters. This results in an EF migration entry that looks like this:

CreateTable(
    "dbo.User",
    c => new
        {
            Name = c.String(nullable: false, maxLength: 30),
              ... Other Properties ...
        });

From an Entity Framework and EF Migration point of view this is exactly what we wanted. Now flip to our client experience with ASP.NET MVC. For our Views, we often use shared templates to generate our forms. This uses the ModelMetadata to build the form. For the Name property, we generate an input plus a span for our validation messages, using the Html.Editor and Html.ValidationMessage helpers. It yields your average label and input combo in the UI (Figure 01).

Figure 01: The Name input Field
Figure 01: The Generated Name input Field

Validating the Validators

Let’s test our client-validation. Looks like our RequiredAttribute prevents blank values, as expected (Figure 02).

Figure 02: The RequiredAttribute at Work
Figure 02: The RequiredAttribute at Work

So far so good, but when we try entering more than 30 characters, no client-side validation is fired allowing us to pass the values on to the server for validation. That’s not the experience that we want. We have client validations for a good user experience and server validations for protection if for some reason something is passed to the server outside our form. You can’t just rely on client validations, but that doesn’t mean that we don’t want them to work!

StringLength: Have Your Cake and Eat It Too

Apparently, I’m not the first one to discover this problem :). There are plenty of questions on StackOverflow related to MaxLength not working for client validations. So what’s the deal? This answer sums it up nicely (republished here):

MaxLength is used for the Entity Framework to decide how large to make a string value field when it creates the database.
From MSDN:

Specifies the maximum length of array or string data allowed in a property.

StringLength is a data annotation that will be used for validation of user input.

From MSDN:

Specifies the minimum and maximum length of characters that are allowed in a data field.

In my testing, StringLength works for both client validation and for Entity Framework (including EF Migrations). It’s an easy change as well, here’s the new code:

[Required]
[StringLength(30)]
public string Name { get; set; }

Now our client validation works as expected (Figure 03).

Figure 03: StringLength Attribute Client Results
Figure 03: StringLength Attribute Client Results

Farewell to MaxLength, StringLength appears to be the attribute to use. I’m not sure why you’d ever want to use MaxLength for strings. Even if this wasn’t in an ASP.NET MVC app, StringLength just seems to make more sense for, well, strings.