简体   繁体   English

实现自定义ModelBinder ASP.NET MVC

[英]Implement custom ModelBinder ASP.NET MVC

I am having the same problem many people already had - Model Binder doesn't accept localized decimal input. 我遇到了很多人已经遇到的相同问题-Model Binder不接受本地化的十进制输入。 In all of the threads, here and other forums, the recommended solution is implementing a custom ModelBinder . 在所有线程中,在这里和其他论坛中,推荐的解决方案是实现自定义ModelBinder

My problem is that those solutions somehow don't work for me. 我的问题是这些解决方案对我不起作用。 Let's use this solution for example: comma decimal seperator in asp.net mvc 5 让我们以以下解决方案为例: asp.net mvc 5中的逗号十进制分隔符

When I reference all namespaces, two errors remain: 当我引用所有名称空间时,仍然存在两个错误:

Error CS0115 'DecimalModelBinder.BindModel(ControllerContext, ModelBindingContext)': no suitable method found to override ... 错误CS0115'DecimalModelBinder.BindModel(ControllerContext,ModelBindingContext)':找不到合适的方法来覆盖...

and

Error CS0173 Type of conditional expression cannot be determined because there is no implicit conversion between 'bool' and 'decimal' 错误CS0173无法确定条件表达式的类型,因为在'bool'和'decimal'之间没有隐式转换

Where the second one references the entire return statement. 第二个引用整个return语句。

Did something change in the MVC Framework, so this code is outdated, or am I doing something wrong? MVC框架中是否发生了某些更改,因此此代码已过时,或者我做错了什么?

The code I ended up with is: 我最终得到的代码是:

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

        }
    }
}

Model property in question: 有问题的模型属性:

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

It seems ultimately what you are trying to achieve is property-level binding such as this?: 看来最终您想要实现的是属性级别的绑定,例如:

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

If that is correct, this post offers a solution: Custom model binder for a property 如果是正确的话,则此帖子提供了一个解决方案: 属性的自定义模型活页夹

Thanks. 谢谢。

In ASP.NET Core 1.1 (Microsoft.AspNetCore.Mvc.Core.Abstraction, 1.0.1.0) you'll see the following interface 在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);
    }
}

Model binders are defined in Microsoft.AspNetCore.Mvc.ModelBinding.Binders namespace, assembly Microsoft.AspNetCore.Mvc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60 . Microsoft.AspNetCore.Mvc.ModelBinding.Binders命名空间,程序集Microsoft.AspNetCore.Mvc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60中定义模型绑定程序。 None of them seem to expose BindModel() method, even less a virtual one. 他们似乎都没有公开BindModel()方法,甚至没有公开虚拟方法。 It looks like you are trying to override a non-existing method. 似乎您正在尝试覆盖不存在的方法。

A better approach is to take an existing ModelBinder , one that best suits your needs, inherit from it, and override ModelBindAsync() . 更好的方法是采用现有的ModelBinder ,它最适合您的需求,从中继承并重写ModelBindAsync()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM