用于小数的Asp.net MVC自定义模型绑定器 - 当十进制操作参数为空时添加模型错误

时间:2017-12-05 15:22:49

标签: asp.net-mvc modelbinders custom-model-binder

我根据Haacked的文章创建了一个自定义模型绑定器。这是代码:

namespace MyNamespace.Project.ModelBinders
{
    public class DecimalModelBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            string modelName = bindingContext.ModelName;
            ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(modelName);

            ModelState modelState = new ModelState { Value = valueResult };

            object actualValue = null;

            try
            {
                //replace commas with periods
                actualValue = Convert.ToDecimal(valueResult.AttemptedValue.Replace(",", "."));
            }
            catch (Exception ex)
            {
                modelState.Errors.Add(ex);
            }

            bindingContext.ModelState.Add(modelName, modelState);

            return actualValue;
        }
    }
} 

当MVC加载一个视图,其中控制器动作是这样的:

public ActionResult Index(decimal amount)  

似乎触发模型绑定并添加错误,这是因为此时的数量为null,因为我有一个有效的用例,其中索引可以加载带或不带参数(QueryString)。据我所知,MVC不支持典型的OO方法重载,因此你有:

public ActionResult Index(decimal amount) {}  
public ActionResult Index() {}  

那么,在我的自定义模型绑定器中添加空检查是否有效以避免在try块中引发的错误,或者这是否会干扰验证?

1 个答案:

答案 0 :(得分:1)

我总体上看到了多个要点。首先是关于这个:

  

据我所知,MVC不支持典型的OO方法重载...

那是对的,但它有一个非常灵活的路线配置来帮助解决这些问题。

您可以为具有参数但没有参数的呼叫配置单独的路由。我没有尝试过,但这是使用Attribute Routing的示例。

[Route("index/{amount}"]
public ActionResult IndexWithAmount(decimal amount) {}  

[Route("index")]
public ActionResult Index() {}

您可以做的另一件事,如described here,不是全局使用Model Binder,而是仅在特定路线上启用它:

public ActionResult Index(
    [ModelBinder(typeof(DecimalModelBinder))]decimal amount) {}