I've just faced a really strange behavior of Razor engine regarding adding unobtrusive validation attributes to inputs in forms. In some cases attributes are not added.
So, I have two similar forms on the same page with similar input elements. They must be submitted to different url's. From model side, I have a few DataAnnotations Attributes, applied to properties to have a client-side validation.
Here is my a bit simplified code of ViewModel:
public class ApplicantPersonalInfo
{
[Required]
[Display(Name = "First Name")]
[StringLength(20, MinimumLength = 2)]
[RegularExpression(@"^[ÀàÂâÆæÇçÉéÈèÊêËëÎîÏïÔôŒœÙùÛûÜüŸÿa-zA-Z \.‘'`-]+$", ErrorMessage = "First Name is in incorrect format")]
public string FirstName { get; set; }
}
Now I want to create two forms. For every of them action url can differ dynamically (I submit them using ajaxSubmit
from jQuery Form Plugin), that's why I decided not to use Html.BeginForm
helper method, instead creating them with simple <form>
tag. So my code is:
<form id="form1">
@Html.TextBoxFor(m => Model.FirstName, new { id = "firstName1" })
</form>
<form id="form2">
@Html.TextBoxFor(m => Model.FirstName, new { id = "firstName2" })
</form>
And the most interesting is the resulting html code:
<form id="form1">
<input data-val="true" data-val-length="The field First Name must be a string with a minimum length of 2 and a maximum length of 20." data-val-length-max="20" data-val-length-min="2" data-val-regex="First Name is in incorrect format" data-val-regex-pattern="^[ÀàÂâÆæÇçÉéÈèÊêËëÎîÏïÔôŒœÙùÛûÜüŸÿa-zA-Z \.‘'`-]+$" data-val-required="The First Name field is required." id="firstName1" name="FirstName" type="text" value=""/>
</form>
<form id="form2">
<input id="firstName2" name="FirstName" type="text" value=""/>
</form>
See? All those validation attributes are not applied to the second input!
BUT if the form is generated using Html.BeginForm
, like this:
@using (Html.BeginForm("NotExistingController", "NotExisitngAtion", FormMethod.Post, new { id = "form1" }))
{
@Html.TextBoxFor(m => Model.HomeOwner.FirstName, new { id = "firstName1" })
}
<form id="form2">
@Html.TextBoxFor(m => Model.HomeOwner.FirstName, new { id = "firstName2" })
</form>
the resulting html code is with attributes in both inputs:
<form action="/NotExisitngAtion/NotExistingController" id="form1" method="post">
<input data-val="true" data-val-length="The field First Name must be a string with a minimum length of 2 and a maximum length of 20." data-val-length-max="20" data-val-length-min="2" data-val-regex="First Name is in incorrect format" data-val-regex-pattern="^[ÀàÂâÆæÇçÉéÈèÊêËëÎîÏïÔôŒœÙùÛûÜüŸÿa-zA-Z \.‘'`-]+$" data-val-required="The First Name field is required." id="firstName1" name="FirstName" type="text" value="" />
</form>
<form id="form2">
<input data-val="true" data-val-length="The field First Name must be a string with a minimum length of 2 and a maximum length of 20." data-val-length-max="20" data-val-length-min="2" data-val-regex="First Name is in incorrect format" data-val-regex-pattern="^[ÀàÂâÆæÇçÉéÈèÊêËëÎîÏïÔôŒœÙùÛûÜüŸÿa-zA-Z \.‘'`-]+$" data-val-required="The First Name field is required." id="firstName2" name="FirstName" type="text" value="" />
</form>
I'm really confused by this behavior. And I've tried - you can add as much forms as you want using Html.BeginForm
- every of them will have set of validation attributes; but if you add >1 form using simple <form>
tag, starting from the second one attributes are missing.
So am I missing something or it's a bug in Razor engine?