【问题标题】:Issues with MVC 4 validation attributes on a production server生产服务器上的 MVC 4 验证属性问题
【发布时间】:2013-11-06 00:14:20
【问题描述】:

我已经研究这个问题好几天了,但一直找不到解决方案。我会尽量具体,以便您了解问题,并在必要时包含代码。

我有一个带有不同控件的 Html.BeginForm(如第一个代码示例中所示)的普通视图,以及其中一些控件的 ValidationMessageFors。在模型(第二个示例)中,我们有一些属性的几个验证属性,就像任何其他 MVC 设置一样。问题是在本地运行页面时,data-val-required 属性以及其他属性都添加到 html 中,但是当部署到生产服务器时,这些属性从未添加,因此验证不会不行。示例 3 和示例 4 显示了这一点。示例 5 显示了脚本文件声明。


示例 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>
}

示例 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; }
}

示例 3(本地):

<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>

示例 4(生产)

<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>

示例 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>

为了节省时间,这是我尝试过的:

  1. 将 requestValidationMode="2.0" 添加到 web.config。
  2. 添加 HtmlHelper.ClientValidationEnabled = true;到视图。
  3. 添加 HtmlHelper.UnobtrusiveJavaScriptEnabled = true;到视图。
  4. 获取最新版本的 jquery 和验证插件。说到jquery,最新的是1.*系列,因为要支持ie8,不能用2.*。
  5. 检查 FormContext 是否为空,如果是则创建一个新的。
  6. 检查是否正在加载脚本。答案是肯定的。
  7. 包括 unobtrusive.ajax。没用。
  8. 将 ClientValidationEnabled 设置为 true,将 UnobtrusiveJavaScriptEnabled 设置为 true。

最后一点:这是在运行 IIS 8 的 Server 2012 机器上。这不是部分视图。

希望你们当中有人遇到过这种情况。我在网上看到的所有地方都说要做这 7 个选项之一,但没有一个有帮助。

编辑: 在调查了很多事情之后(自原始发布以来的几天),我发现 window.mvcClientValidationMetadata 属性被设置为 javascript 中的正确规则,但缺少连接,因此在运行验证时,字段实际上没有经过验证。

【问题讨论】:

  • 没有想法?这个问题导致我们的许多测试失败,因为没有一个客户端验证有效。

标签: c# validation asp.net-mvc-4 razor attributes


【解决方案1】:

只是提供一些线索。

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

创建span的方法如下:

    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 application cache,请清除它或更新清单。

【讨论】:

  • 在视图中使用 Html.EnableClientValidation() 之前,我已经显示了跨度,但是由于没有检测到任何验证,它只是使用以下 html 创建了一个跨度:*
  • 另外,我关闭了缓存。这并没有解决问题。
  • 如果 UnobtrusiveJavaScriptEnabled 为假,那是跨度格式...我已经没有想法了
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-26
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 2013-09-21
    • 2011-11-15
    • 1970-01-01
    相关资源
    最近更新 更多