【问题标题】:How can I add model binding support for a new non-complex type?如何为新的非复杂类型添加模型绑定支持?
【发布时间】:2014-01-14 07:16:08
【问题描述】:

我有一个控制器动作,它采用自定义类型的参数:

public class SomeController : Controller
{
    public ActionResult Index(CustomType someValue)
    {
        throw new NotImplementedException();
    }
}

ASP.NET MVC 不知道自定义类型,它不是“复杂”类型;它需要自定义创建逻辑:

public class CustomType
{
    public CustomType(string data){}
}

在这个例子中,我希望能够告诉 ASP.NET MVC,每当它需要绑定到 CustomType 时,它应该使用以下过程:

(string someRequestValue) => new CustomType(someRequestValue)

我快速浏览了一下这里和谷歌,但我没有找到任何涵盖这个简单场景的东西。

【问题讨论】:

    标签: .net asp.net-mvc model-binding


    【解决方案1】:

    Bart 的回答非常有效,我认为它适合您的情况。但是,如果您需要更改默认模型绑定行为,最好通过实现 IModelBinder 接口来实现您自己的模型绑定对象,该接口公开一个单一方法 BindModel

    public class CustomTypeModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var valueReceived = bindingContext.ValueProvider.GetValue("actionParam").AttemptedValue;
            return new CustomType(valueReceived);
        }
    }
    

    那么只要在你的应用启动时注册模型绑定器就可以了……

    protected void Application_Start()
    {
           ModelBinders.Binders.Add(typeof(CustomType), new CustomTypeModelBinder());
    }
    

    但是,如上所述,你真的不需要走这条路……我认为

    【讨论】:

    • 你赢了我一分钟;)不错!
    • 哎呀...对不起伙计:)...谁在乎呢?只要对那里的开发者社区做出足够且有意义的贡献;)
    • 牦牛...阅读您的评论,我想按赞按钮 LOL.. 来自其他社交网站的习惯...
    • 谢谢!看起来你的实现只有在动作参数被称为 actionParam 时才能工作。如何实现它只依赖于CustomType而不是特定的参数?
    • 别在意我的最后评论;我已经找到了自己的方法。感谢您为我指明正确的方向!
    【解决方案2】:

    正如Leo's answer 中所建议的,这可以通过实现IModelBinder 并注册CustomType 的实现来完成。可以通过支持任何操作参数而不是仅支持具有特定名称的参数来改进该实现。我还添加了空值检查,以便行为与内置模型绑定一致。

    模型绑定器

    public class CustomTypeModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext,
            ModelBindingContext bindingContext)
        {
            var valueName = bindingContext.ModelName;
            var value = bindingContext.ValueProvider.GetValue(valueName);
            if (value == null)
                return null;
    
            var textValue = value.AttemptedValue;
            return new CustomType(textValue);
        }
    }
    

    注册

    protected void Application_Start()
    {
        ModelBinders.Binders.Add(typeof(CustomType), new CustomTypeModelBinder());
    }
    

    【讨论】:

      【解决方案3】:

      为什么不:

      public class SomeController : Controller
      {
          public ActionResult Index(string someValue)
          {
              var obj = new CustomType(someValue);
          }
      }
      

      【讨论】:

      • 因为我希望我的动作逻辑简洁并专注于实际逻辑而不是基础架构。
      • 另外,我希望在多个操作方法中使用CustomType,并且我不想用重复的模型绑定逻辑来混淆它们。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-05
      • 1970-01-01
      相关资源
      最近更新 更多