【问题标题】:MVC4 Validation with razor and twitter bootstrap使用 razor 和 twitter 引导程序进行 MVC4 验证
【发布时间】:2013-08-21 15:27:51
【问题描述】:

我需要在 MVC4 razor 中验证我的输入。问题是,我想使用 twitter 引导程序,然后为顶部 div 设置错误消息类,如下所示:http://getbootstrap.com/css/#forms-control-states

如何更改父 div 的班级?

【问题讨论】:

    标签: twitter-bootstrap asp.net-mvc-4 razor unobtrusive-validation


    【解决方案1】:

    你试过这个脚本吗?

    http://blog.ijasoneverett.com/2013/05/asp-net-mvc-validation-with-twitters-bootstrap/

    我使用类似的东西来获得引导程序和 mvc 验证以发挥良好的作用

    【讨论】:

    【解决方案2】:

    接受的答案需要修改才能与 Bootstrap 3 一起使用。我已成功使用 following 与 MVC 4 和 Bootstrap 3。

    $(function () {
     // any validation summary items should be encapsulated by a class alert and alert-danger
        $('.validation-summary-errors').each(function () {
            $(this).addClass('alert');
            $(this).addClass('alert-danger');
        });
    
        // update validation fields on submission of form
        $('form').submit(function () {
            if ($(this).valid()) {
                $(this).find('div.control-group').each(function () {
                    if ($(this).find('span.field-validation-error').length == 0) {
                        $(this).removeClass('has-error');
                        $(this).addClass('has-success');
                    }
                });
            }
            else {
                $(this).find('div.control-group').each(function () {
                    if ($(this).find('span.field-validation-error').length > 0) {
                        $(this).removeClass('has-success');
                        $(this).addClass('has-error');
                    }
                });
                $('.validation-summary-errors').each(function () {
                    if ($(this).hasClass('alert-danger') == false) {
                        $(this).addClass('alert');
                        $(this).addClass('alert-danger');
                    }
                });
            }
        });
    
        // check each form-group for errors on ready
        $('form').each(function () {
            $(this).find('div.form-group').each(function () {
                if ($(this).find('span.field-validation-error').length > 0) {
                    $(this).addClass('has-error');
                }
            });
        });
    });
    
    var page = function () {
        //Update the validator
        $.validator.setDefaults({
            highlight: function (element) {
                $(element).closest(".form-group").addClass("has-error");
                $(element).closest(".form-group").removeClass("has-success");
            },
            unhighlight: function (element) {
                $(element).closest(".form-group").removeClass("has-error");
                $(element).closest(".form-group").addClass("has-success");
            }
        });
    }();
    

    【讨论】:

      【解决方案3】:

      修改验证器默认值:

      // Override jquery validate plugin defaults in order to utilize Twitter Bootstrap 3 has-error, has-success, etc. styling.
      $.validator.setDefaults({
          highlight: function(element) {
              $(element).closest('.form-group').addClass('has-error').removeClass('has-success');
          },
          unhighlight: function(element) {
              $(element).closest('.form-group').removeClass('has-error').addClass('has-success');
          },
          errorElement: 'span',
          errorClass: 'help-block',
          errorPlacement: function (error, element) {
              if (element.parent('.input-group').length || element.prop('type') === 'checkbox' || element.prop('type') === 'radio') {
                  error.insertAfter(element.parent());
              } else {
                  error.insertAfter(element);
              }
          }
      });
      

      创建一个新的验证摘要部分(这样您就可以完全控制标记):

      @model ModelStateDictionary
      
      <div class="@(Html.ViewData.ModelState.IsValid ? "validation-summary-valid" : "validation-summary-errors") panel panel-danger" data-valmsg-summary="true">
          <div class="panel-heading">
              Please, correct the following errors:
          </div>
          <div class="panel-body">
              <ul>
                  @foreach (var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
                  {
                      <li>@modelError.ErrorMessage</li>
                  }
              </ul>
          </div>
      </div>
      

      向您的 CSS 添加一种样式(以在初始加载时隐藏验证摘要,而无需依赖客户端脚本在事后将其隐藏):

      .validation-summary-valid { 
          display: none; 
      }
      

      并在您的视图中呈现您的替代验证摘要,而不是 @Html.ValidationSummary():

         @{Html.RenderPartial("_HtmlValidationSummary", ViewData.ModelState);}
      

      你可以走了。哦,要获得复选框和收音机的漂亮样式,根据您的设置,上面的脚本会捕获它,但最简单的方法是简单地将您的 ie Boolean.cshtml 部分修改为如下所示(其中 Html.FormGroupFor 只是一个https://github.com/erichexter/twitter.bootstrap.mvc/blob/master/src/Bootstrap/BootstrapSupport/ControlGroupExtensions.cs 的略微更新版本 - 只需将“control-group”引用更改为“form-group”并在第 58 行添加“controlGroupWrapper.AddCssClass(“has-error”);”):

      @using Bctf.Web.HtmlHelpers
      @model bool?
      
      @using (Html.FormGroupFor(x => Model))
      {
          <label class="checkbox">
              @Html.CheckBox("", Model.HasValue && Model.Value, new { @class = "tickbox-single-line" }) @ViewData.ModelMetadata.DisplayName
          </label>
          @Html.ValidationMessageFor(x => Model, string.Empty, new { @class = "help-block" })
      }
      

      以上所有内容都是我从许多不同位置找到的各种解决方案的汇编,这些解决方案已经做出了正确的组合。 Ben 的上述解决方案有效,但它在客户端执行了相当多的操作,每当调用其中的某些方法(即发布、页面加载、验证错误)时都会导致抖动。以上内容可以满足您的所有需求,而无需所有 DOM 循环。

      Bootstrap 3 with jQuery Validation Plugin 找到的各种答案涵盖了上述大部分内容(并且上述大部分内容的功劳归功于那里的各种海报,尽管没有一个答案涵盖所有内容)。

      【讨论】:

        【解决方案4】:

        解决方案

        包括最后一个:

        $.validator.unobtrusive.options = {
            errorPlacement: function (error, element) {        
                $(element).closest(".form-group").addClass("has-error");
            }
            , success: function (label, element) {
                $(element).closest(".form-group").removeClass("has-error");        
            }
        }
        

        目前在 jquery.validate.unobtrusive.js 中,以下代码显示了 MS 如何允许扩展自身:

        options: {  // options structure passed to jQuery Validate's validate() method
            errorClass: defaultOptions.errorClass || "input-validation-error",
            errorElement: defaultOptions.errorElement || "span",
            errorPlacement: function () {
                onError.apply(form, arguments);
                execInContext("errorPlacement", arguments);
            },
            invalidHandler: function () {
                onErrors.apply(form, arguments);
                execInContext("invalidHandler", arguments);
            },
            messages: {},
            rules: {},
            success: function () {
                onSuccess.apply(form, arguments);
                execInContext("success", arguments);
            }
        }
        

        允许您基本上覆盖/扩展以下选项:

        • 错误类
        • 错误元素
        • 错误放置
        • 无效处理程序
        • 成功

        它通过查看全局变量 $.validator.unobtrusive.options 来实现这一点(除非你创建它,否则它不存在)。 defaultOptions 设置为 $.validator.unobtrusive.optionsexecInContext 是在 $.validator.unobtrusive.options 中找到适用方法并使用原始参数执行它的方法(这样原始 MS 方法就不会被破坏)。

        【讨论】:

          【解决方案5】:

          我喜欢在服务器端添加类,而不是在客户端,所以,我的解决方案没有 javascript(在我的例子中,它是一个简单的系统,表单上只有 2 或 3 个字段)。

          这是为了使用来自 Bootstrap 文档的 Form -> Validation States 中的相同结构,可在 http://getbootstrap.com/css/#forms-control-validation 中找到

          首先,我创建了一个Html Helper 来检查ModelState 是否有效,如果该字段有错误,则返回一个字符串(类名)。我可以直接在视图上执行此操作,但我喜欢更清晰的视图。所以,我的班级:

          public static class ErrorHelper
          {
              private static string GetPropertyName<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
              {
                  // Get field name
                  // Code from: https://stackoverflow.com/a/2916344/4794469
                  MemberExpression body = expression.Body as MemberExpression;
                  if (body != null) return body.Member.Name;
          
                  UnaryExpression ubody = expression.Body as UnaryExpression;
                  if (ubody != null) body = ubody.Operand as MemberExpression;
          
                  return body?.Member.Name;
              }
          
              public static MvcHtmlString ReturnOnError<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, string @class)
              {
                  var propertyName = GetPropertyName(expression);
                  if (propertyName == null)
                      return MvcHtmlString.Empty;
          
                  if (htmlHelper.ViewData.ModelState.IsValid || !htmlHelper.ViewData.ModelState.ContainsKey(propertyName))
                      return MvcHtmlString.Empty;
          
                  return htmlHelper.ViewData.ModelState[propertyName].Errors.Any()
                      ? MvcHtmlString.Create(@class)
                      : MvcHtmlString.Empty;
              }
          }
          

          进口:

          using System;
          using System.Linq;
          using System.Linq.Expressions;
          using System.Web.Mvc;
          

          现在,在我看来,我只需要使用该类,例如:

          <div class="form-group @Html.ReturnOnError(m => m.Name, "has-error")">
              @Html.LabelFor(m => m.Name, new { @class = "control-label" })
              @Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
              @Html.ValidationMessageFor(m => m.Name, null, new { @class = "help-block" })
          </div>
          

          【讨论】:

            猜你喜欢
            • 2014-06-06
            • 2014-12-27
            • 2015-09-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-05-20
            相关资源
            最近更新 更多