【问题标题】:how to get model in custom model binder?如何在自定义模型绑定器中获取模型?
【发布时间】:2014-02-12 13:26:45
【问题描述】:

我正在尝试使用以下代码创建自定义模型绑定器:

public class TransactionModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        Object Model = bindingContext.Model;

        //Do custom logic

        return Model;
    }
}

在 global.asax 中,我添加:

ModelBinders.Binders.Add(typeof(TransViewModel), new TransactionModelBinder());

问题: 我不确定如何获得模型。我试过bindingContext.Model,但它是空的。 如果我在 Global.asax 中的代码行是否正常,还请指导。

【问题讨论】:

    标签: c# .net asp.net-mvc asp.net-mvc-4


    【解决方案1】:

    看到这个article

    public class HomeCustomDataBinder : DefaultModelBinder
    {
    
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(HomePageModels))
            {
                HttpRequestBase request = controllerContext.HttpContext.Request;
    
                string title = request.Form.Get("Title");
                string day = request.Form.Get("Day");
                string month = request.Form.Get("Month");
                string year = request.Form.Get("Year");
    
                return new HomePageModels
                {
                    Title = title,
                    Date = day + "/" + month + "/" + year
                };
    
                //// call the default model binder this new binding context
                //return base.BindModel(controllerContext, newBindingContext);
            }
            else
            {
                return base.BindModel(controllerContext, bindingContext);
            }
        }
    
    } 
    

    【讨论】:

      【解决方案2】:

      好吧,如果您打算从头开始编写整个活页夹,您将没有模型。相反,您实际上是从表单数据创建模型的人(因为这就是活页夹的用途)。如:

      return new SomeModel 
      {
          OneProp = request.Form["OneProp"],
          AnotherProp = request.Form["AnotherProp"]
      }
      

      或者,您可以从DefaultModelBinder 继承而不是IModelBinder,您可以使用它仅扩展某些行为,而不是实际处理模型的构造。

      编辑:

      根据您的 cmets,我了解到您只想处理您可能拥有的多个视图模型中的一个属性(可能多个视图模型具有来自视图的小数,其格式与 MVC 对小数的期望格式不同。

      在这种情况下,我实际上会使用不同的方法。我不会在 global.asax 中注册 ModelBinder,而是将其从那里删除,并在需要该特殊格式的实际属性上以声明方式进行。

      如:

      [PropertyBinder(typeof(MyDecimalBinder))]
      public decimal SomePropInAViewModel {get; set;}
      

      这是基于创建 PropertyBindingAttribute 的常用方法: http://www.prideparrot.com/blog/archive/2012/6/customizing_property_binding_through_attributeshttps://stackoverflow.com/a/12683210/1373170

      还有一个类似这样的 ModelBinder:

      public class MyDecimalBinder :  DefaultModelBinder {
          protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) {
      
              // use the propertyDescriptor to make your modifications, by calling SetProperty()
              ...
      
              base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
          }
      
      }
      

      现在,如果您想将此应用于所有小数,您可能还想查看 Phil Haack 关于使用自定义活页夹处理小数的完整实现:​​

      http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx/

      【讨论】:

      • 同意。如果您能提供更多指导,将不胜感激。你说的是来自模型,我应该修改一个属性并返回属性而不是完整的模型吗?在我之前尝试过之前。只需修改一个小数属性。问题:不幸的是,在 Global.asax 中,我已经有一个带十进制的客户活页夹。我试过: ModelBinders.Binders.Add(typeof(decimal), new CurrencyModelBinder()); ModelBinders.Binders.Add(typeof(decimal), new TxTransactionModelBinder());但出现错误“已添加具有相同密钥的项目。”
      • 这是否意味着在 global.asax 中我可以注册 2 个相同 typeof 的自定义模型绑定器(在本例中为 typeof(decimal))?我很欣赏你的方法,但只是想问一下,这不可能吗?如果你必须从 global.asax 做,你会怎么做?
      • 我不认为你可以为同一类型拥有多个自定义绑定器,这没有多大意义(这类似于拥有两个具有相同参数但返回类型不同的函数),但是对于小数,您似乎只需要一个。如果您想在所有视图模型中允许小数点中的分隔符,我会选择 Phil Haack 的实现;)
      • 我在一些 PropertyBinder 实现上添加了一些链接。但是,我认为在您的场景中,Phil 的实现可能更简单。
      猜你喜欢
      • 2022-12-16
      • 1970-01-01
      • 2012-02-18
      • 2012-01-29
      • 2012-07-31
      • 2011-02-08
      • 2018-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多