2

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:

  1. Adding requestValidationMode="2.0" to the web.config.
  2. Adding HtmlHelper.ClientValidationEnabled = true; to the view.
  3. Adding HtmlHelper.UnobtrusiveJavaScriptEnabled = true; to the view.
  4. 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.*.
  5. Checking if the FormContext is null and creating a new one if it is.
  6. Checking if the scripts are being loaded. The answer is yes.
  7. Including unobtrusive.ajax. Doesn't help.
  8. 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.

4

2 回答 2

0

只是提供一些线索。

将 ClientValidationEnabled 设置为 true 应该会创建一个 span 标签,即使您没有包含 JQuery 并将 UnobtrusiveJavaScriptEnabled 设置为 true

这是创建跨度的方法:

    private static MvcHtmlString ValidationMessageHelper(this HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression, string validationMessage, IDictionary<string, object> htmlAttributes)
    {
        string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
        FormContext clientValidation = htmlHelper.ViewContext.GetFormContextForClientValidation();
        if (!htmlHelper.ViewData.ModelState.ContainsKey(fullHtmlFieldName) && clientValidation == null)
            return (MvcHtmlString)null;

        ModelState modelState = htmlHelper.ViewData.ModelState[fullHtmlFieldName];
        ModelErrorCollection modelErrorCollection = modelState == null ? (ModelErrorCollection)null : modelState.Errors;
        ModelError error = modelErrorCollection == null || modelErrorCollection.Count == 0 ? (ModelError)null : Enumerable.FirstOrDefault<ModelError>((IEnumerable<ModelError>)modelErrorCollection, (Func<ModelError, bool>)(m => !string.IsNullOrEmpty(m.ErrorMessage))) ?? modelErrorCollection[0];
        if (error == null && clientValidation == null)
            return (MvcHtmlString)null;

        TagBuilder tagBuilder = new TagBuilder("span");
        ...
        return TagBuilderExtensions.ToMvcHtmlString(tagBuilder, TagRenderMode.Normal);
    }

也许您正在访问缓存的输出?检查:

  1. Sserver 未返回缓存版本
  2. 如果您使用HTML5 应用程序缓存,请清除它或更新清单。
于 2013-11-08T13:26:16.473 回答
0

好吧,看来我不小心修复了它。我对 Web 配置进行了更改,使其无效,将其推送到生产环境,然后得到了与之相关的好 ol' 错误。所以我解决了这个问题,并推高了曾经存在的东西,突然一切都奏效了。

据我所知,IIS 以某种方式读取了不同的 Web 配置或某种隐藏缓存中的内容,直到出现无效缓存才将其清除。奇怪,但至少现在它是固定的。

附带说明一下,我意外添加了第二个模块节点,导致 web.config 错误,试图将 runAllManagedModulesForAllRequests 设置为 true,但它已经存在。如果其他人遇到类似的问题,我希望导致 web.config 错误然后修复它可以解决您的问题。

于 2013-11-08T23:28:11.150 回答