5

Một số decimaldecimal? thuộc tính trong mô hình quan điểm của tôi được đánh dấu là "Phần trăm" kiểu dữ liệu, cùng với chú thích các dữ liệu khác, ví dụ:Thao tác giá trị mô hình trước khi đi qua nó để DefaultModelBinder.BindModel

[DataType("Percent")] 
[Display(Name = "Percent of foo completed")] 
[Range(0, 1)] 
public decimal? FooPercent { get; set; } 

Tôi muốn cho phép người dùng linh hoạt về cách họ nhập dữ liệu, tức là có hoặc không có dấu phần trăm, khoảng trắng trung gian, v.v. Nhưng tôi vẫn muốn sử dụng hành vi DefaultModelBinder để nhận tất cả chức năng của nó như kiểm tra RangeAttribute và thêm thông báo xác thực thích hợp.

Có cách nào để phân tích cú pháp và thay đổi giá trị mô hình, sau đó chuyển nó theo? Đây là những gì tôi đang cố gắng, nhưng tôi nhận được một ngoại lệ thời gian chạy. (Bỏ qua logic phân tích thực tế, điều này không phải là hình thức cuối cùng của nó Tôi chỉ quan tâm đến các câu hỏi mô hình thay thế vào thời điểm này..)

public class PercentModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, 
            ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelMetadata.DataTypeName == "Percent") 
     { 
      ValueProviderResult result = 
       bindingContext.ValueProvider.GetValue(
        bindingContext.ModelName); 
      if (result != null) 
      { 
       string stringValue = 
        (string)result.ConvertTo(typeof(string)); 
       decimal decimalValue; 
       if (!string.IsNullOrWhiteSpace(stringValue) && 
        decimal.TryParse(
         stringValue.TrimEnd(new char[] { '%', ' ' }), 
         out decimalValue)) 
       { 
        decimalValue /= 100.0m; 

        // EXCEPTION : This property setter is obsolete, 
        // because its value is derived from 
        // ModelMetadata.Model now. 
        bindingContext.Model = decimalValue; 
       } 
      } 
     } 

     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

Trả lời

5

Đừng bận tâm, đây là một sự hiểu lầm cơ bản của nơi xác nhận xảy ra trong Chu trình MVC. Sau khi chi tiêu một số thời gian trong mã nguồn MVC, tôi thấy cách làm việc này.

Trong trường hợp nó rất có ích cho người khác, đây là những gì đang làm việc cho tôi:

[DataType("Percent")] 
[Display(Name = "Percent of foo completed")] 
[Range(0.0d, 1.0d, ErrorMessage="The field {0} must be between {1:P0} and {2:P0}.")] 
public decimal? FooPercent { get; set; } 

Và trong các chất kết dính, bạn chỉ cần trả về giá trị:

public class PercentModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, 
            ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelMetadata.DataTypeName == "Percent") 
     { 
      ValueProviderResult result = 
       bindingContext.ValueProvider.GetValue(
        bindingContext.ModelName); 
      if (result != null) 
      { 
       string stringValue = 
        (string)result.ConvertTo(typeof(string)); 
       decimal decimalValue; 
       if (!string.IsNullOrWhiteSpace(stringValue) && 
        decimal.TryParse(
         stringValue.TrimEnd(new char[] { '%', ' ' }), 
         out decimalValue)) 
       { 
        return decimalValue/100.0m; 
       } 
      } 
     } 

     return base.BindModel(controllerContext, bindingContext); 
    } 
} 
+0

Đối với tôi, chất kết dính tùy chỉnh là không bao giờ được thực hiện. Bạn còn đang làm gì khác không? –

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