52

The DataAnnotations validator not working in asp.net mvc 4 razor view, when using the special characters in the regular expression.

Model:

[StringLength(100)]
[Display(Description = "First Name")]
[RegularExpression("^([a-zA-Z0-9 .&'-]+)$", ErrorMessage = "Invalid First Name")]
public string FirstName { get; set; }

Razor View:

@Html.TextBoxFor(model => Model.FirstName, new { })
@Html.ValidationMessageFor(model => Model.FirstName)

The unobtrusive validation is rendered in view as:

<input type="text" value="" tabindex="1" style="height:auto;" name="FirstName" maxlength="100" id="FirstName" data-val-regex-pattern="^([a-zA-Z0-9 .&amp;amp;&amp;#39;-]+)$" data-val-regex="Invalid First Name" data-val-length-max="100" data-val-length="The field FirstName must be a string with a maximum length of 100." data-val="true" class="textfield ui-input-text ui-body-d ui-corner-all ui-shadow-inset valid">

The regex pattern in the above html is not rendered as specified in the Model's RegularExpression, which results in error even when entering the valid data (Sam's).

How can i handle this?

--UPDATE--

I have updated the code as per @Rick suggestion

[StringLength(100)]
[Display(Description = "First Name")]
[RegularExpression("([a-zA-Z0-9 .&'-]+)", ErrorMessage = "Enter only alphabets and numbers of First Name")]
public string FirstName { get; set; }

View Source shows the following:

<input data-val="true" data-val-length="The field FirstName must be a string with a maximum length of 100." data-val-length-max="100" data-val-regex="Enter only alphabets and numbers of First Name" data-val-regex-pattern="([a-zA-Z0-9 .&amp;amp;&amp;#39;-]+)" id="FirstName" maxlength="100" name="FirstName" type="text" value="" />

Still i have the same issue.

2
  • We just had a similar issue where we want a "&nbsp;" to be spit out in the ErrorMessage.. Commented Dec 21, 2011 at 13:41
  • Hi, i'm collegue of TweeZz ;] Yes, we've fixed it in the end, but it was rather crude fix. When spitting out unobtrusive validation attributes we htmlDecoded all validation messages for regex validators, you could do the same for your case. Commented Jan 5, 2012 at 14:09

9 Answers 9

36

UPDATE 9 July 2012 - Looks like this is fixed in RTM.

  1. We already imply ^ and $ so you don't need to add them. (It doesn't appear to be a problem to include them, but you don't need them)
  2. This appears to be a bug in ASP.NET MVC 4/Preview/Beta. I've opened a bug

View source shows the following:

data-val-regex-pattern="([a-zA-Z0-9 .&amp;&#39;-]+)"                  <-- MVC 3
data-val-regex-pattern="([a-zA-Z0-9&#32;.&amp;amp;&amp;#39;-]+)"      <-- MVC 4/Beta

It looks like we're double encoding.

Sign up to request clarification or add additional context in comments.

1 Comment

Rick is right, for sure it is a bug. The &' is Html encoded twice. The first html encoding yields &amp;&#34; The socond encoding html encode again the two & getting: &amp;amp;&amp;#34. There is no easy way to fix. The only way might be to htmldecode the attribute value once it arrive on the client during unobtrusive parsing
13

Try escaping those characters:

[RegularExpression(@"^([a-zA-Z0-9 \.\&\'\-]+)$", ErrorMessage = "Invalid First Name")]

4 Comments

Still the same result: <input type="text" value="" tabindex="1" style="height:auto;" name="FirstName" maxlength="100" id="FirstName" data-val-regex-pattern="^([a-zA-Z0-9 \.\&amp;amp;\&amp;#39;\-]+)$" data-val-regex="Invalid First Name" data-val-length-max="100" data-val-length="The field FirstName must be a string with a maximum length of 100." data-val="true" class="textfield ui-input-text ui-body-d ui-corner-all ui-shadow-inset input-validation-error">
What if you put double \\ in the regex?
Either double \\, or @ in front of the opening " like Darin had in his example.
@Darin, Its converting any special character i add in the regex as in my question.
5

Try @ sign at start of expression. So you wont need to type escape characters just copy paste the regular expression in "" and put @ sign. Like so:

[RegularExpression(@"([a-zA-Z\d]+[\w\d]*|)[a-zA-Z]+[\w\d.]*", ErrorMessage = "Invalid username")]
public string Username { get; set; }

Comments

2

This one worked for me, try this

[RegularExpression("^[a-zA-Z &\-@.]*$", ErrorMessage = "--Your Message--")]

1 Comment

When possible, please make an effort to provide additional explanation instead of just code. Such answers tend to be more useful as they help members of the community and especially new developers better understand the reasoning of the solution, and can help prevent the need to address follow-up questions.
1

What browser are you using? I entered your example and tried in both IE8 and Chrome and it validated fine when I typed in the value Sam's

 public class IndexViewModel
 {
    [Required(ErrorMessage="Required")]
    [RegularExpression("^([a-zA-Z0-9 .&'-]+)$", ErrorMessage = "Invalid First Name")]
    public string Name { get; set; }
 }

When I inspect the DOM using IE Developer toolbar and Chrome Developer mode it does not show any special characters.

5 Comments

I tried in Firefox, IE and chrome. My application is developed using asp.net mvc 4(C#). asp.net/mvc/mvc4
If you exclude the unobtrusive jquery script, does your validation work correctly?
When i exclude "jquery.validate.unobtrusive.min.js", the client side validation is not working.
Not working as in Client Side doesn't fire? Or Sam's still does not validate correctly?
As client side is not working, it's not validating the Sam's properly
1

We've had similar issue in the past (as mentioned by TweeZz). In our case we're controlling outputting of TextBoxFor by our custom htmlHelper extension method which is building MvcHtmlString, there in one step we need to add these unobtrusive validation attributes, which is done via

var attrs = htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata)

after call to this method, attributes are html encoded, so we simply check if there was Regular expression validator there and if so, we html unencode this attribute and then merge them into tagBuilder (for building "input" tag)

if(attrs.ContainsKey("data-val-regex"))
    attrs["data-val-regex"] = ((string)attrs["data-val-regex"]).Replace("&amp;","&");
tagBuilder.MergeAttributes(attrs);

We only cared about & amps, that's why this literal replacement

1 Comment

In general we needed more control over the rendering of certain attributes (stackoverflow.com/questions/6016500/…) so we decided to copy paste (and modify) the MVC source code for certain helper methods. There doesn't seem to be another way..
0

Try using the ASCII code for those values:

^([a-zA-Z0-9 .\x26\x27-]+)$
  • \x26 = &
  • \x27 = '

The format is \xnn where nn is the two-digit hexadecimal character code. You could also use \unnnn to specify a four-digit hex character code for the Unicode character.

1 Comment

Even With this i am not getting it: <input type="text" value="" tabindex="1" style="height:auto;" name="FirstName" maxlength="100" id="FirstName" data-val-regex-pattern="^([a-zA-Z0-9 .&amp;amp;&amp;#39;-]+)$" data-val-regex="Invalid First Name" data-val-length-max="100" data-val-length="The field FirstName must be a string with a maximum length of 100." data-val="true" class="textfield ui-input-text ui-body-d ui-corner-all ui-shadow-inset input-validation-error">
0

The problem is that the regex pattern is being HTML encoded twice, once when the regex is being built, and once when being rendered in your view.

For now, try wrapping your TextBoxFor in an Html.Raw, like so:

@Html.Raw(Html.TextBoxFor(model => Model.FirstName, new { }))

3 Comments

Though i used @Html.Raw, still the regex renders as encoded. It works fine with my ASP.NET MVC 3 application, the problem is only with MVC4 application.
With @Html.Raw, was the regex still double encoded? In MVC3, I use AntiXSS as the default encoder. My regexes are encoded once, and work without any issue.
Even when i use @Html.Raw, its encoding. I am using ASP.NET MVC 4 asp.net/mvc/tutorials/aspnet-mvc-4-mobile-features
0

Try this one in model class

    [Required(ErrorMessage = "Enter full name.")]
    [RegularExpression("([A-Za-z])+( [A-Za-z]+)", ErrorMessage = "Enter valid full name.")]

    public string FullName { get; set; }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.