I have been working on this issue for several days now and have been unable to find a solution. I will try to be as specific as I can, so that you understand the problem, and include code where necessary.
I have a normal view with a Html.BeginForm (as seen in the first code example) with different controls inside, as well as ValidationMessageFors for some of them. In the model (the second example) we have a couple validation attributes for some of the properties, just like any other MVC setup. The issue is that locally when the page is run, the data-val-required attribute, as well as others, are all added to the html, but when deployed to the production server, these attributes are never added, and so the validation doesn't work. Examples 3 and 4 show this. Example 5 shows the script file declarations.
Example 1:
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.HiddenFor(model => model.DocumentID);
@Html.HiddenFor(model => model.TempFilePath);
@Html.HiddenFor(model => model.FileName);
<div style="height: 27px; width: 769px; background-color: #b3b3b3; padding-top: 7px; padding-right: 14px; padding-left: 14px; border-bottom: 1px solid #808080;">
<span style="font-size: 11.5pt; font-weight: bold; float: left;">@ViewBag.Title</span>
</div>
<br />
<div style="margin-left: 15px; margin-right: 15px;">
@Html.ValidationSummary(true)
<h4>Document Name</h4>
@Html.TextBoxFor(model => model.Name, new { id = "DocumentNameEdit" })
@Html.ValidationMessageFor(model => model.Name, "*", new { @style = "font-size:16pt;" })
<br />
<h4>Description</h4>
@Html.TextAreaFor(model => model.Description, new { id = "DocumentDescriptionEdit" })
@Html.ValidationMessageFor(model => model.Description, "*", new { @style = "font-size:16pt;" })
<br />
<input type="button" id="btnSaveDocument" value="Save" />
<input type="button" id="btnClose" value="Close" />
</div>
}
Example 2:
public class DocumentModel
{
public DocumentModel()
{
Statuses = new List<SelectListItem>()
{
new SelectListItem() {Text="Visible", Value="3"},
new SelectListItem() {Text="Hidden", Value="4"}
};
}
public string DocumentID { get; set; }
[StringLength(255, ErrorMessage = "Please enter no more than 255 characters for the Name.")]
[Required(ErrorMessage="Name is Required") ]
public string Name { get; set; }
[StringLength(2000, ErrorMessage = "Please enter no more than 2000 characters for the Description.")]
[Required(ErrorMessage = "Description is Required")]
public string Description { get; set; }
public string FileName { get; set; }
public int? Status { get; set; }
public string FolderID { get; set; }
public string TempFilePath { get; set; }
public List<dm_LIST_Folders_Result> FolderList { get; set; }
public List<SelectListItem> Statuses { get; set; }
}
Example 3 (local):
<form method="post" action="/DPS/Documents/CreateEdit" novalidate="novalidate">
<input type="hidden" value="TheCode" name="__RequestVerificationToken">
<input type="hidden" value="" name="DocumentID" id="DocumentID">
<input type="hidden" value="" name="TempFilePath" id="TempFilePath">
<input type="hidden" value="" name="FileName" id="FileName">
<div style="height: 27px; width: 769px; background-color: #b3b3b3; padding-top: 7px; padding-right: 14px; padding-left: 14px; border-bottom: 1px solid #808080;">
<span style="font-size: 11.5pt; font-weight: bold; float: left;">Add New Document</span>
</div>
<br>
<div style="margin-left: 15px; margin-right: 15px;">
<h4>Document Name</h4>
<input type="text" value="" name="Name" id="DocumentNameEdit" data-val-required="Name is Required" data-val-length-max="255" data-val-length="Please enter no more than 255 characters for the Name." data-val="true">
<span style="font-size:16pt;" data-valmsg-replace="false" data-valmsg-for="Name" class="field-validation-valid">*</span>
<br>
<h4>Description</h4>
<textarea rows="2" name="Description" id="DocumentDescriptionEdit" data-val-required="Description is Required" data-val-length-max="2000" data-val-length="Please enter no more than 2000 characters for the Description." data-val="true" cols="20"></textarea>
<span style="font-size:16pt;" data-valmsg-replace="false" data-valmsg-for="Description" class="field-validation-valid">*</span>
<br>
<input type="button" value="Save" id="btnSaveDocument">
<input type="button" value="Close" id="btnClose">
</div>
</form>
Example 4 (Production)
<form method="post" action="/DM/DPS/Documents/CreateEdit" novalidate="novalidate">
<input type="hidden" value="TheCode" name="__RequestVerificationToken">
<input type="hidden" value="" name="DocumentID" id="DocumentID">
<input type="hidden" value="" name="TempFilePath" id="TempFilePath">
<input type="hidden" value="" name="FileName" id="FileName">
<div style="height: 27px; width: 769px; background-color: #b3b3b3; padding-top: 7px; padding-right: 14px; padding-left: 14px; border-bottom: 1px solid #808080;">
<span style="font-size: 11.5pt; font-weight: bold; float: left;">Add New Document</span>
</div>
<br>
<div style="margin-left: 15px; margin-right: 15px;">
<h4>Document Name</h4>
<input type="text" value="" name="Name" id="Name">
<br>
<h4>Description</h4>
<textarea rows="2" name="Description" id="Description" cols="20"></textarea>
<br>
<input type="button" value="Save" id="btnSaveDocument">
<input type="button" value="Close" id="btnClose">
</div>
</form>
Example 5:
@Scripts.Render("~/bundles/jquery")
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
Just to save on time, here is what I have tried:
- Adding requestValidationMode="2.0" to the web.config.
- Adding HtmlHelper.ClientValidationEnabled = true; to the view.
- Adding HtmlHelper.UnobtrusiveJavaScriptEnabled = true; to the view.
- Getting the most recent version of jquery and the validate plugin. When it comes to jquery, the most recent is 1.* series, since we have to support ie8 and can't use 2.*.
- Checking if the FormContext is null and creating a new one if it is.
- Checking if the scripts are being loaded. The answer is yes.
- Including unobtrusive.ajax. Doesn't help.
- Setting ClientValidationEnabled to true and UnobtrusiveJavaScriptEnabled to true.
A final note: this is on a Server 2012 machine running IIS 8. This is not a partial view.
Hopefully one of you have run into this. Everywhere I look online says to do one of those 7 options, and none have helped.
Edit: After looking into things for quite a bit more (couple days since original posting) I have found that the window.mvcClientValidationMetadata property is being set to the correct rullings in the javascript, but the hookups are missing, so when validation is run, the fields aren't actually validated.