public class Feedback
{
[Required(ErrorMessage= "Name is required.")]
[StringLength(30,ErrorMessage="Name can not be longer than 30 characters.")]
public string FullName { get; set; }
[Required(ErrorMessage = "Email is required.")]
[Email(ErrorMessage = "Invalid email format.")]
public string EmailAddress { get; set; }
[Required(ErrorMessage="URL is required.")]
public string PrimaryURL { get; set; }
[StringLength(500,ErrorMessage="Message can't be longer than 500 characters.")]
public string Message { get; set; }
}
public class EmailAttribute : RegularExpressionAttribute
{
public EmailAttribute()
: base("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$")
{
}
}
The client validation works on the Required and Stringlength attributes, but if I put an incorrectly formatted email, it still returns successful. Is there a special way to do the regular expression attribute? Or am I doing it wrong?
This actually has nothing to do with the fact you are using Ajax.BeginForm(). It would happen if you were using Html.BeginForm() as well. It’s happening because MVC doesn’t know that your EmailAttribute should be validated as a RegularExpressionAttrbiute.
You have two options:
<div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y:
hidden;" id="_mcePaste">One, just use the RegularExpressionAttribute on your model instead of your custom EmailAttribute:</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div>
<div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste">Or, teach your EmailAttribute that it should be validated using the same adapter as the RegularExpressionAttribute uses:</div>
<div></div><div>One, just use the RegularExpressionAttribute on your model instead of your custom EmailAttribute:</div><div>
</div><div>Or, teach your EmailAttribute that it should be validated using the same adapter as the RegularExpressionAttribute uses:</div></div><div>
public class EmailAttribute : RegularExpressionAttribute
{
public EmailAttribute()
: base("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$") { }
static EmailAttribute()
{
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EmailAttribute), typeof(RegularExpressionAttributeAdapter));
}
}
</div><div>Edit:</div><div>I have no idea why the forums is blocking the regular expression in the first code block, but you likely
know what supposed to go there. :) I think you should just use the second option anyhow. </div>
This should go in Application_Start, not the EmailAttribute static constructor.
It works either way. I use the static method so that the class is self registering, you don't end up with a lot of ceremony in your Global.asax. It's cleaner IMO.
Now, if there is a technical reason why this isn't a good idea, I love to know it, as I use this technique pretty often.
Now, if there is a technical reason why this isn't a good idea, I love to know it, as I use this technique pretty often.
There's no guarantee that the static constructor has run before the mapping dictionary is consumed by the validation provider. (It's perfectly valid for us to start caching entries, for example, and the static constructor can run
after we've built up this cache.) The fact that this works in MVC 2 is solely an implementation detail, and it's not guaranteed to hold going forward.
Marked as answer by ricka6 on Mar 26, 2010 06:40 PM
Dalze
Member
75 Points
10 Posts
AJAX.BeginForm and Html.ValidationSummary
Mar 22, 2010 08:39 PM|LINK
I am trying to make an AJAX Form work correctly with Client Validation, but I can't seem to figure out how to make it work together.
Currently I have a view like this:
<% Html.EnableClientValidation(); %> <div class="Form"> <% using (Ajax.BeginForm(new AjaxOptions { HttpMethod = "Post", OnSuccess = "Testing" })) { %> <%= Html.ValidationSummary(false, "Could not send feedback, please correct errors.", new { style = "text-align: center;" })%> <div style="width: 320px; margin: 0 auto;"> <p> <label for="FullName">Full Name:</label> <%= Html.TextBox("FullName",Model.FullName)%> <%= Html.ValidationMessageFor(m => m.FullName, "*")%> </p> <p> <label for="EmailAddress">Email Address:</label> <%= Html.TextBox("EmailAddress",Model.EmailAddress)%> <%= Html.ValidationMessageFor(m => m.EmailAddress,"*") %> </p> <p> <label for="FullName">Primary URL:</label> <%= Html.TextBox("PrimaryURL", Model.PrimaryURL)%> <%= Html.ValidationMessageFor(m => m.PrimaryURL, "*")%> </p> <p> <label for="Message" style='vertical-align: top;'>Message/Question:</label> <%= Html.TextArea("Message",Model.Message)%> <%= Html.ValidationMessageFor(m => m.Message, "*")%> </p> <p> </p> <p style='text-align: center;'> <input type="submit" value="Submit" /> </p> <% } %> </div>My model:
public class Feedback { [Required(ErrorMessage= "Name is required.")] [StringLength(30,ErrorMessage="Name can not be longer than 30 characters.")] public string FullName { get; set; } [Required(ErrorMessage = "Email is required.")] [Email(ErrorMessage = "Invalid email format.")] public string EmailAddress { get; set; } [Required(ErrorMessage="URL is required.")] public string PrimaryURL { get; set; } [StringLength(500,ErrorMessage="Message can't be longer than 500 characters.")] public string Message { get; set; } } public class EmailAttribute : RegularExpressionAttribute { public EmailAttribute() : base("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$") { } }The client validation works on the Required and Stringlength attributes, but if I put an incorrectly formatted email, it still returns successful. Is there a special way to do the regular expression attribute? Or am I doing it wrong?
ignatandrei
All-Star
134917 Points
21621 Posts
Moderator
MVP
Re: AJAX.BeginForm and Html.ValidationSummary
Mar 23, 2010 12:30 PM|LINK
Please put controller code...
Nick Riggs
Member
502 Points
81 Posts
Re: AJAX.BeginForm and Html.ValidationSummary
Mar 23, 2010 03:13 PM|LINK
This actually has nothing to do with the fact you are using Ajax.BeginForm(). It would happen if you were using Html.BeginForm() as well. It’s happening because MVC doesn’t know that your EmailAttribute should be validated as a RegularExpressionAttrbiute. You have two options:
<div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste">One, just use the RegularExpressionAttribute on your model instead of your custom EmailAttribute:</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste">Or, teach your EmailAttribute that it should be validated using the same adapter as the RegularExpressionAttribute uses:</div> <div></div><div>One, just use the RegularExpressionAttribute on your model instead of your custom EmailAttribute:</div><div>[RegularExpression("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$", ErrorMessage = "Invalid email format.")] public string EmailAddress { get; set; }</div><div>Or, teach your EmailAttribute that it should be validated using the same adapter as the RegularExpressionAttribute uses:</div></div><div>public class EmailAttribute : RegularExpressionAttribute { public EmailAttribute() : base("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$") { } static EmailAttribute() { DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EmailAttribute), typeof(RegularExpressionAttributeAdapter)); } }</div><div>Edit:</div><div>I have no idea why the forums is blocking the regular expression in the first code block, but you likely know what supposed to go there. :) I think you should just use the second option anyhow. </div>levib
Star
7702 Points
1099 Posts
Microsoft
Re: AJAX.BeginForm and Html.ValidationSummary
Mar 23, 2010 05:18 PM|LINK
This should go in Application_Start, not the EmailAttribute static constructor.
Nick Riggs
Member
502 Points
81 Posts
Re: AJAX.BeginForm and Html.ValidationSummary
Mar 23, 2010 05:52 PM|LINK
It works either way. I use the static method so that the class is self registering, you don't end up with a lot of ceremony in your Global.asax. It's cleaner IMO.
Now, if there is a technical reason why this isn't a good idea, I love to know it, as I use this technique pretty often.
Dalze
Member
75 Points
10 Posts
Re: AJAX.BeginForm and Html.ValidationSummary
Mar 23, 2010 06:04 PM|LINK
Why thank you!
That worked perfectly, before I would have to POST to the controller to be able to receive the validation, it is now working on the client side.
Much thanks!
levib
Star
7702 Points
1099 Posts
Microsoft
Re: AJAX.BeginForm and Html.ValidationSummary
Mar 23, 2010 06:18 PM|LINK
There's no guarantee that the static constructor has run before the mapping dictionary is consumed by the validation provider. (It's perfectly valid for us to start caching entries, for example, and the static constructor can run after we've built up this cache.) The fact that this works in MVC 2 is solely an implementation detail, and it's not guaranteed to hold going forward.
Nick Riggs
Member
502 Points
81 Posts
Re: AJAX.BeginForm and Html.ValidationSummary
Mar 23, 2010 06:26 PM|LINK
Thanks for the explanation Levib. I'll need to change this behavior in an open source project I'm working on.
Dalze, as Levib suggested, it would be best to move the follow line of code to your Global.asax.cs Application_Start method:
Dalze
Member
75 Points
10 Posts
Re: AJAX.BeginForm and Html.ValidationSummary
Mar 23, 2010 06:52 PM|LINK
Thanks a lot guys, it's working great!