实现自定义ModelBinder ASP.NET MVC

时间:2017-08-20 19:05:00

标签: c# .net asp.net-mvc asp.net-mvc-5 model-binding

我遇到了许多人已经遇到的同样问题 - Model Binder不接受本地化的十进制输入。在所有线程,此处和其他论坛中,推荐的解决方案是实现自定义ModelBinder

我的问题是那些解决方案不知何故不适合我。让我们使用此解决方案,例如:comma decimal seperator in asp.net mvc 5

当我引用所有名称空间时,仍然存在两个错误:

  

错误CS0115' DecimalModelBinder.BindModel(ControllerContext,   ModelBindingContext)':找不到合适的方法来覆盖...

  

错误CS0173无法确定条件表达式的类型   因为' bool'之间没有隐含的转换。和'十进制'

第二个引用整个return语句。

MVC框架中有什么变化,所以这段代码已经过时,或者我做错了什么?

我最终得到的代码是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.ModelBinding;
using System.Web.Mvc;

namespace AetMuzickaOprema.App_Start
{
    public class DecimalModelBinder : System.Web.ModelBinding.DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, System.Web.ModelBinding.ModelBindingContext bindingContext) //first error
        {
            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

            return valueProviderResult == null ? base.BindModel(controllerContext, bindingContext) : Convert.ToDecimal(valueProviderResult.AttemptedValue); //second error

        }
    }
}

有问题的模型属性:

[Required]
[Range(typeof(decimal), "0", "999999999")]
public decimal Price { get; set; }

2 个答案:

答案 0 :(得分:1)

最终你想要实现的是属性级绑定,比如这个?:

[PropertyBinder(typeof(PropertyBBinder))]
public IList<int> PropertyB {get; set;}

如果这是正确的,这篇文章提供了一个解决方案:Custom model binder for a property

感谢。

答案 1 :(得分:1)

在ASP.NET Core 1.1(Microsoft.AspNetCore.Mvc.Core.Abstraction,1.0.1.0)中,您将看到以下界面

using System.Threading.Tasks;

namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
    //
    // Summary:
    //     Defines an interface for model binders.
    public interface IModelBinder
    {
        //
        // Summary:
        //     Attempts to bind a model.
        //
        // Parameters:
        //   bindingContext:
        //     The Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext.
        //
        // Returns:
        //     A System.Threading.Tasks.Task which will complete when the model binding process
        //     completes.
        //     If model binding was successful, the Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext.Result
        //     should have Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.IsModelSet
        //     set to true.
        //     A model binder that completes successfully should set Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext.Result
        //     to a value returned from Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.Success(System.Object).
        Task BindModelAsync(ModelBindingContext bindingContext);
    }
}

模型绑定器在Microsoft.AspNetCore.Mvc.ModelBinding.Binders命名空间,程序集Microsoft.AspNetCore.Mvc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60中定义。他们似乎都没有公开BindModel()方法,更不用虚拟方法了。看起来您正试图覆盖不存在的方法。

更好的方法是采用现有的ModelBinder,最适合您的需求,从中继承,并覆盖ModelBindAsync()