SimonF
SimonF

Reputation: 824

Handling line breaks in textarea elements with ASP MVC and jquery unobtrusive validation

Viewmodel:

public class ViewModel
{
    [Display(Name = "Message")]
    [StringLength(500, ErrorMessage = "Your message must be {1} characters or fewer.")]
    public string Message { get; set; }
}

View (extract):

<div class="form-field-group">
    @Html.LabelFor(m => m.Message , "Your message:")
    @Html.TextAreaFor(m => m.Message )
    @Html.ValidationMessageFor(m => m.Message )
</div>

I'm also using the unobtrusive validation like so in the web.config:

<appSettings>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>

Absolutely textbook stuff, and it seems to work wonderfully.

The problem!

So my understanding of the HTML spec for line breaks in form data is that it gets encoded as CR LF. And that's certainly what I see when I debug the controller action that handles the post of this viewmodel.

However, when reading the value of the input through javascript, the line breaks vary depending on browser (IE6-8 seem to give CRLF whereas Chrome and Firefox recent builds on windows give just LF).

This means that if you enter text with line breaks, the jquery validators will let through what they see as, say, 498 characters, but by the time it reaches the model binding, it's been converted to 504 and ModelState.IsValid is (correctly) false.

Anyone got any ideas about the nicest/simplest way to correct this?

Upvotes: 2

Views: 1352

Answers (1)

DalSoft
DalSoft

Reputation: 11107

MVC unobtrusive validation (jquery.validate.unobtrusive.js) makes use of jquery.validate.js.

So the simplest way to fix this issue is to change the behavior of what maxlength does in jquery.validate.js (this is what jquery.validate.unobtrusive.js attaches to via it's adapter).

The code below will change maxlength and fix the issue:

(function ($) {

    if ($.validator && $.validator.methods && $.validator.methods.maxlength) {

        $.validator.methods.maxlength = function (value, element, param) {
            if (typeof value === 'string') {
                value = value.replace(/\r?\n/g, "\r\n");
            }

            var length = $.isArray(value) ? value.length : $.validator.prototype.getLength($.trim(value), element);
            return $.validator.prototype.optional(element) || length <= param;
        };
    }

})(jQuery);

Something to note is this won't cause an issue on non windows platforms (or cause different issues) http://en.wikipedia.org/wiki/Newline.

You could also solve this by creating your own validation attribute and implementing IClientValidatable adding your own client side validation http://www.falconwebtech.com/post/2012/04/21/MVC3-Custom-Client-Side-Validation-with-Unobtrusive-Ajax.aspx. The disadvantage of this is remembering to use your attribute rather than standard StringLength one. You have to decide what is best for your situation.

Upvotes: 2

Related Questions