0

在我已創建自定義模型粘結劑和IModelBinderProvider處理貨幣asp.net的MVC應用程序時,貨幣被髮布到幾千格式的服務器,像$123,456.00ASP.NET模型綁定基於屬性

我想調用自定義的模型綁定只有模型的屬性應用了某個屬性。下面是我的代碼

public interface IScrubberAttribute 
{ 
    object Scrub(string modelValue, out bool success); 
} 

public class CurrencyScrubberAttribute : Attribute, IScrubberAttribute 
{  
    public object Scrub(string modelValue, out bool success) 
    { 
     // do something 
    } 
} 

public class ScrubbingModelBinder : DefaultModelBinder 
{ 
    IScrubberAttribute _attribute; 

    public ScrubbingModelBinder(Type type, IScrubberAttribute attribute) 
    { 
     _attribute = attribute as IScrubberAttribute; 
    } 

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     // do something 
    } 
} 

public class ScrubbingModelBinderProvider : IModelBinderProvider 
{ 
    public IModelBinder GetBinder(Type modelType) 
    { 
     if (modelType == typeof(decimal) || modelType == typeof(decimal?)) 
     { 

      //??? ISSUE: the line below always returns null. 
      var attribute = modelType.GetCustomAttributes(typeof(CurrencyScrubberAttribute), false).FirstOrDefault(); 
      if (attribute != null) 
      { 
       return new ScrubbingModelBinder(modelType, attribute as IScrubberAttribute); 
      } 
     } 

     return null; 
    } 
} 

我的模型

public class MyModel 
{ 
    [CurrencyScrubber]  
    public decimal? MyValue { get; set; } 
} 

我在應用程序啓動時註冊ScrubbingModelBinderProvider所以得到調用它。

問題
ScrubbingModelBinderProvider我試圖找到,如果已申請了財產[CurrencyScrubber]屬性;如果只是調用ScrubbingModelBinder
但是modelType.GetCustomAttributes()方法無法找到或返回CurrancyScrubber屬性。當我在調試模式下進行快速的手錶,該modelType.GetCustomAttributes()方法返回3個屬性,但沒有一個類型CurrancyScrubber

回答

0

IModelBinderProvider方法我張貼在原來的問題在asp.net核心應用中使用,並在asp.net核心作品。我試圖在經典的asp.net中使用相同的方法。然而在傳統的asp.net中,你無法獲得自定義屬性。相關SO post here and here

所以要解決這個問題,我重寫的System.Web.Mvc.DefaultModelBinderBindProperty方法哪裏可以得到自定義屬性

public class ScrubbingModelBinder : DefaultModelBinder 
{  
    public ScrubbingModelBinder() 
    {   
    }  

    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) 
    { 
     var propBindAttr = propertyDescriptor.Attributes.OfType<CurrencyScrubberAttribute>().FirstOrDefault(); 
     if (propBindAttr != null && 
      (propertyDescriptor.PropertyType == typeof(decimal) || propertyDescriptor.PropertyType == typeof(decimal?))) 
     { 
      var value = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name); 
      if (value != null && value.AttemptedValue != null) 
      { 
       var success = true; 
       var result = propBindAttr.Scrub(value.AttemptedValue, out success); 
       if (success) 
       { 
        propertyDescriptor.SetValue(bindingContext.Model, result); 
        return; 
       } 
      } 
     } 

     base.BindProperty(controllerContext, bindingContext, propertyDescriptor); 
    } 
} 

,然後在Application_Start()方法DefaultBinder註冊。沒有必要使用IModelBinderProvider

ModelBinders.Binders.DefaultBinder = new ScrubbingModelBinder(); 

所以現在默認粘結劑將像以前一樣用於所有的屬性,除了有[CurrencyScrubber]屬性之一。