Asp.net mvc 在将模型值传递给DefaultModelBinder.BindModel之前对其进行操作

Asp.net mvc 在将模型值传递给DefaultModelBinder.BindModel之前对其进行操作,asp.net-mvc,asp.net-mvc-3,model-binding,defaultmodelbinder,Asp.net Mvc,Asp.net Mvc 3,Model Binding,Defaultmodelbinder,我的视图模型中的一些decimal和decimal?属性与其他数据注释一起标记为“百分比”数据类型,例如: [DataType("Percent")] [Display(Name = "Percent of foo completed")] [Range(0, 1)] public decimal? FooPercent { get; set; } 我希望允许用户在输入数据的方式上有一定的灵活性,即使用或不使用百分号、中间空格等。但我仍然希望使用DefaultModelBinder行为来获取其

我的视图模型中的一些
decimal
decimal?
属性与其他数据注释一起标记为“百分比”数据类型,例如:

[DataType("Percent")]
[Display(Name = "Percent of foo completed")]
[Range(0, 1)]
public decimal? FooPercent { get; set; }
我希望允许用户在输入数据的方式上有一定的灵活性,即使用或不使用百分号、中间空格等。但我仍然希望使用
DefaultModelBinder
行为来获取其所有功能,例如检查
RangeAttribute
并添加适当的验证消息

有没有办法解析和更改模型值,然后传递它?这是我正在尝试的,但是我得到了一个运行时异常。(忽略实际的解析逻辑;这不是它的最终形式。我现在只对模型替换问题感兴趣。)


没关系,这是对MVC周期中验证发生在何处的根本误解。在花了一些时间研究MVC源代码之后,我看到了它是如何工作的

如果这对其他人有帮助,以下是对我有效的方法:

[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; }
在活页夹中,您只需返回值:

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

对我来说,自定义活页夹从未执行过。你还有别的事要做吗?
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);
    }
}