MVC 3中的百分比属性

Dav*_*eer 9 asp.net-mvc model-binding

我的应用程序有许多模型,其中许多包含百分比数据.这些在模型中表示为decimaldecimal?结构.但是,并非所有具有decimal结构的属性都是百分比.有些应该像常规小数一样对待.

百分比需要特别注意:

  • 为了显示,他们应该使用{0:P2}格式.(我有这部分工作.)
  • 对于编辑,它们应该允许与显示相同的格式,即"95"或"95%"或"95.00%"都绑定到值0.95.

我开始走上创建之路PercentModelBinder实现IModelBinder,但后来意识到,你只能应用ModelBinderAttribute,而不是一个属性.

处理这种情况的最佳方法是什么,某种类型的(但不是全部)使用需要对显示和绑定进行特殊处理?

我认为每个解决方案都有过分杀戮,与MVC框架作斗争.当然有一种比以下更好的方法:

  • 创建自定义Percentage结构并将其用作IModelBinder和EditorTemplates的基础,或
  • 重新实现和的默认绑定行为,decimaldecimal?根据对模型的深入了解来改变解析逻辑,或者
  • 为包含百分比属性的每个类实现自定义模型绑定器,或
  • 在模型中使用伪代理属性(即打破MVC)

Dar*_*rov 15

一种可能性是编写自定义元数据感知属性:

public class PercentageAttribute : Attribute, IMetadataAware
{
    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.AdditionalValues["percentage"] = metadata.EditFormatString;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后用它来装饰表示百分比的视图模型属性:

public class MyViewModel
{
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
    [Percentage]
    public decimal? Percentage { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并在自定义模型绑定器测试内部存在此值:

public class PercentageModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelMetadata.AdditionalValues.ContainsKey("percentage"))
        {
            var format = (string)bindingContext.ModelMetadata.AdditionalValues["percentage"];
            // TODO: do the custom parsing here
            throw new NotImplementedException();
        }
        else
        {
            // Let the default parsing occur
            return base.BindModel(controllerContext, bindingContext);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以将此模型绑定器注册到所有小数.