ASP.NET MVC 2 client-side validation triggering incorrectly
I am using DataAnnotations to enable client-side validation in an ASP.NET MVC 2 project. I am having an issue where my URL validation regex passes my unit test, but it fails in the actual website.
Model
[RegularExpression(UrlValidation.Regex, ErrorMessage = UrlValidation.Message)]
public string Url { get; set; }
Regex = "(([\w]+:)?//)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+开发者_StackOverflow[\w]{2,4}(:[\d]+)?(/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?"
Message = "Invalid Url"
View
<div class="editor-label">
<%: Html.LabelFor(model => model.Url) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Url) %>
<%: Html.ValidationMessageFor(model => model.Url) %>
</div>
Result With URL = http://www.chicagoshakes.com/main.taf?p=7,8
Passing Unit Test
[Test]
public void GetVarUrlPasses()
{
var url = "http://www.chicagoshakes.com/main.taf?p=7,8";
var regex = new Regex(UrlValidation.Regex);
Assert.IsTrue(regex.IsMatch(url));
}
Does anyone have any idea why this is passing the unit test, but failing when I test the view in a browser?
I can see several problems with that regex, but what's tripping you up is probably the comma in p=7,8
. Your regex doesn't match it, but IsMatch
doesn't require it to; it's perfectly happy stopping at the 7
. I would guess that the client-side validator is implicitly anchoring the match. The regex should be anchored anyway; add a ^
to the beginning and $
to the end, and you should at least get consistent results. Then you can change the regex to accommodate the comma.
There's also a typo in the regex: the second f
in [a-fA-f\d]
should be F
. And, although it's not an error to have \d
and \w
in the same set of square brackets, it is redundant; \w
matches digits as well as letters, so you can remove the \d
(and [\w\d]
can be reduced to \w
). Finally, {2,2}
should be simply {2}
.
Because it's passing the unit test, the problem may be in your controller or model. Is Url
ever directly accessed?
Alan Moore was basically right, the regex was junk. I ended up using a this regex.
Also, here's the proper way to write the unit test:
[Test]
public void GetVarUrlPasses()
{
var url = "http://www.chicagoshakes.com/main.taf?p=7,8";
var attribute = new RegularExpressionAttribute(regex);
Assert.IsTrue(regex.IsValid(url));
}
精彩评论