2012-04-02 43 views
13

Tôi đang cố gắng xác thực phía khách hàng của mình (mô hình ràng buộc) để hỗ trợ các nền văn hóa khác nhau và tôi tìm thấy một blog thú vị về chủ đề mà tôi đang cố gắng triển khai.Xác thực phía máy khách MVC 3, giá trị thập phân và giá trị thập phân của mô hình (dấu tách thập phân khác nhau)

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

Poco

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

    public string Name { get; set; } 

    public decimal Salary { get; set; } 
    } 

Tôi đã có DecimalModelBinder lớp tùy chỉnh của tôi

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

web.config của tôi:

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

Global.asax được thay đổi để sử dụng ModelBinder tùy chỉnh của tôi trên thập phân và thập phân? giá trị

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); 
} 

Vẫn xác thực phía máy khách không thành công được nhập vào dấu thập phân của tôi bằng dấu "," làm dấu phân cách thập phân. Nó không xử lý cả "," và ".". Việc xác thực js dường như không có ràng buộc tùy chỉnh của tôi khi xem xét

Đọc lại bài viết trên blog, tôi dường như không thể tìm ra những gì tôi đang thiếu.

Dưới đây là quan điểm:

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

Server side validation có vẻ tốt đẹp, nhưng làm thế nào để xử lý các xác nhận client-side để gửi một POST khi nhấp vào nút gửi.

Xác thực javascript không xử lý dấu phẩy. phiên bản enter image description here enter image description here

Trả lời

19

Cuối cùng, bằng cách hiểu rằng DecimalModelBinder tùy chỉnh sẽ chỉ xử lý xác thực phía máy chủ và không ảnh hưởng đến jquery.validate.js xử lý xác thực phía máy khách, tôi đã tìm thấy giải pháp cho sự cố.

Mở rộng xác thực đã giải quyết được sự cố của tôi.

enter image description here

Mở rộng xác nhận bởi một file .js mới như một cách giải quyết cho vấn đề:

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

Blog này là thực sự hữu ích http://rebuildall.umbraworks.net/2011/03/02/jQuery_validate_and_the_comma_decimal_separator

+0

Bạn vẫn cần DecimalModelBinder một khi bạn mở rộng xác nhận? – Romias

+0

Có, bạn có. Nếu không thì ModelBinder (phía máy chủ) sẽ thêm Lỗi. Trong thực tế, bạn có thể làm chỉ với DecimalModelBinder, nếu bạn không muốn xác thực trước POST. – Kman

+0

Cảm ơn bạn đã giải quyết nó và cảm ơn bạn đã đăng giải pháp –

4

Hãy thử điều này nó chút thay đổi:

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

Nó làm việc cho tôi.

CẬP NHẬT

Nếu bạn đang sử dụng một cái nhìn sử dụng một phần $.validate.unobtrusive.parse("#selector") để nộp đơn xin xác nhận. Nếu không thử đặt toàn cầu hóa trên web của bạn.cấu hình (một trong thư mục gốc, không phải trong Views) để một cái gì đó như thế này:

<configuration> 
    <system.web> 
    <globalization fileEncoding="utf-8" 
        requestEncoding="utf-8" 
        responseEncoding="utf-8" 
        culture="hr-HR" uiCulture="hr-HR" /> 
    </system.web> 
</configuration> 

Tôi có toàn cầu hóa thiết lập để Hr nơi chúng ta dùng dấu phẩy để phân cách nhưng với DecimalModelBinder tôi đã đăng nó sẽ đúng cách phân tích số thập phân hoặc dấu phẩy . Kính trọng

+0

Tôi sẽ dùng thử. Nhưng mối quan tâm chính của tôi là điểm dừng của tôi không bị đánh trúng. Vì vậy, nếu mã không bao giờ được thực hiện, tôi không thấy làm thế nào thay đổi nên giải quyết vấn đề của tôi – Kman

+0

Nếu bạn nhấn hành động bài viết của bạn? và đã làm tất cả mọi thứ như bạn nói như vậy sau đó tôi thấy không có lý do tại sao breakpoints của bạn không trúng. Cập nhật –

+1

: Trình kết hợp mô hình thập phân tùy chỉnh của tôi được kích hoạt trên bản cập nhật thực tế, nhưng xác thực phía khách hàng vẫn không thành công. Tôi sẽ cập nhật bài đăng chính của mình. Vấn đề là xác nhận TRƯỚC KHI bài đăng được gửi – Kman

1

Tôi vừa cố định vấn đề này thay thế dòng 1050 của jquery.validate.js bằng mã này:

trả về this.optional (phần tử) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:[.|\,]\d+)?$/.test(value) ;

Tôi vừa thay đổi smth trên cụm từ thông dụng được sử dụng để xác thực số và giờ nó hoạt động tuyệt vời !!

Các vấn đề liên quan