MVC 3客户端验证,模型绑定十进制值和文化(不同的小数分隔符)

Kma*_*man 14 model asp.net-mvc-3

我正在尝试进行客户端验证(模型绑定)以支持不同的文化,我发现了一个有趣的博客,我正在尝试实现该主题.

http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx

波科

  public class Jogador
  {
    public int ID { get; set; }

    public string Name { get; set; }

    public decimal Salary { get; set; }
  }
Run Code Online (Sandbox Code Playgroud)

我有自定义的DecimalModelBinder类

  public class DecimalModelBinder : IModelBinder
  {
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
      ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
      ModelState modelState = new ModelState {Value = valueResult};

      object actualValue = null;
      try
      {
        actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
      }
      catch (FormatException e)
      {
        modelState.Errors.Add(e);
      }

      bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
      return actualValue;
    }
  }
Run Code Online (Sandbox Code Playgroud)

我的web.config:

<compilation debug="true" targetFramework="4.0">
  <assemblies>
    <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  </assemblies>
</compilation>

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>

<pages>
  <namespaces>
    <add namespace="System.Web.Helpers" />
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
    <add namespace="System.Web.WebPages"/>
  </namespaces>
</pages>
Run Code Online (Sandbox Code Playgroud)

更改Global.asax以使用我的自定义ModelBinder十进制和十进制?值

protected void Application_Start()
{
  AreaRegistration.RegisterAllAreas();

  ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
  ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());

  RegisterGlobalFilters(GlobalFilters.Filters);
  RegisterRoutes(RouteTable.Routes);
}
Run Code Online (Sandbox Code Playgroud)

仍然客户端验证在我的视图中输入的十进制失败,并带有","作为小数分隔符.它不处理","和".".js验证似乎没有考虑我的自定义绑定

一遍又一遍地阅读博客文章,我似乎无法弄清楚我错过了什么.

这是观点:

@model MVC_Empty.Web.Models.Jogador

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Jogador</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Salary)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Salary)
            @Html.ValidationMessageFor(model => model.Salary)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
Run Code Online (Sandbox Code Playgroud)

服务器端验证似乎很好,但是如何处理客户端验证以便在单击提交按钮时发送POST.

javascript验证不处理逗号.在此输入图像描述 在此输入图像描述

Kma*_*man 19

最后,通过了解Custom DecimalModelBinder只处理服务器端验证而不影响处理客户端验证的jquery.validate.js,我找到了问题的解决方案.

扩展验证解决了我的问题.

在此输入图像描述

通过新的.js文件扩展验证,作为问题的解决方法:

$.validator.methods.number = function(value, element) {
  return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/ .test(value);
};
Run Code Online (Sandbox Code Playgroud)

这个博客非常有用 http://rebuildall.umbraworks.net/2011/03/02/jQuery_validate_and_the_comma_decimal_separator


Mat*_*cic 5

试试这个稍微修改过的版本:

 public class DecimalModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext,
            ModelBindingContext bindingContext)
        {
            ValueProviderResult valueResult = bindingContext.ValueProvider
                .GetValue(bindingContext.ModelName);
            ModelState modelState = new ModelState { Value = valueResult };
            object actualValue = null;
            try
            {
                //if with period use InvariantCulture
                if (valueResult.AttemptedValue.Contains("."))
                {
                    actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
                    CultureInfo.InvariantCulture);
                }
                else
                {
                    //if with comma use CurrentCulture
                    actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
                    CultureInfo.CurrentCulture);
                }

            }
            catch (FormatException e)
            {
                modelState.Errors.Add(e);
            }

            bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
            return actualValue;
        }
    }
Run Code Online (Sandbox Code Playgroud)

这个对我有用.

UPDATE

如果您使用部分视图用于$.validate.unobtrusive.parse("#selector")重新应用验证.如果没有尝试在web.config中设置全局化(根目录中的一个,而不是在视图中),请执行以下操作:

<configuration>
  <system.web>
    <globalization fileEncoding="utf-8" 
                    requestEncoding="utf-8" 
                    responseEncoding="utf-8" 
                    culture="hr-HR" uiCulture="hr-HR" />
  </system.web>
</configuration>
Run Code Online (Sandbox Code Playgroud)

我将全球化设置为Hr,我们使用逗号作为分隔符,但是我发布的DecimalModelBinder将正确解析小数或逗号.问候