我如何可以调用MVC4自定义模型绑定? [英] How can I invoke a custom model binder in MVC4?

查看:181
本文介绍了我如何可以调用MVC4自定义模型绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以好像几个人(如<一个href=\"http://geekswithblogs.net/jdothoffman/archive/2012/03/06/mvc-4-beta-web-api-bug-with-binding-route-values.aspx\"相对=nofollow>这里和<一个href=\"http://blogs.msdn.com/b/carlosfigueira/archive/2012/02/27/disabling-model-binding-on-asp-net-web-apis-beta.aspx\"相对=nofollow>这里)曾与 MVC4模型ApiControllers 的结合,但他们的问题似乎很满足,我看到的问题。

所有我真的很想做的是改变数组绑定行为为整数的列表。所以说,我有一个请求类型如下:

 公共类MyRequestModel
{
    公开名单&LT;长&GT; ListOfIntegers {搞定;组; }    ...
}

和一个API GET方法是这样的:

 公共ResultsResponseModel获取(MyRequestModel要求)
{
    //使用request.ListOfIntegers有意义    ...    返回响应;
}

我基本上要能够说 / API /结果/?listOfIntegers = 1 + 2 + 3 + 4 + 5 和有决心的列表&LT;长方式&gt; 属性

我试过我平常的模型绑定的招数,但与大多数在 MVC4在Web API的它似乎有模型绑定一个完全独立的路径。

我是使用 System.Web.Http.ModelBinding.ModelBinder 属性的 MyRequestModel 得到最远,并创建一个模型绑定的实施 System.Web.Http.ModelBinding.IModelBinder 。一贯产生具有堆栈跟踪的对象引用异常,永远不会碰我的code。

任何人打呢?有什么想法,尝试下?

更新:这是我在我的自定义已经捕获了堆栈跟踪 ExceptionFilterAttribute

对象引用未设置到对象的实例。
    在System.Web.Http.ModelBinding.DefaultActionValueBinder.BindParameterValue(HttpActionContext ActionContext中,HttpParameterBinding parameterBinding)
    在System.Web.Http.ModelBinding.DefaultActionValueBinder.<>c__DisplayClass1.BindValuesAsync>b__0(RequestContentReadKind contentReadKind)
    在System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass38.<ToAsyncVoidTask>b__37()
    在System.Threading.Tasks.TaskHelpers.RunSynchronously [TResult](Func`1 FUNC键的CancellationToken的CancellationToken)


解决方案

如果你说ApiControllers,那么你想绑定的网络API模型,现在MVC
下面是一个示例模型绑定

 公共类MyRequestModelBinderProvider:ModelBinderProvider
    {
        MyRequestModelBinder粘结剂=新MyRequestModelBinder();
        公共IdeaModelBinderProvider()
        {
        }        公众覆盖IModelBinder GetBinder(HttpActionContext ActionContext中,ModelBindingContext的BindingContext)
        {
            如果(bindingContext.ModelType == typeof运算(MyRequestModel))
            {
                返回粘结剂;
            }            返回null;
        }
    }

下面是注册自定义模型绑定提供的一个例子

 的IEnumerable&LT;对象&gt; modelBinderProviderServices = GlobalConfiguration.Configuration.ServiceResolver.GetServices(typeof运算(ModelBinderProvider));
 清单&LT;对象&gt;服务=新的List&LT;对象&gt;(modelBinderProviderServices);
 services.Add(新MyRequestModelBinderProvider());
 GlobalConfiguration.Configuration.ServiceResolver.SetServices(typeof运算(ModelBinderProvider),services.ToArray());

现在您的自定义模型绑定使用上下文来访问查询字符串值

 公共类MyRequestModelBinder:IModelBinder
    {
        公共MyRequestModelBinder()
        {        }        公共BOOL BindModel(HttpActionContext ActionContext中,ModelBindingContext的BindingContext)
        {
            MyRequestModel yourModel;
            //使用上下文来访问查询字符串值
            //创建/更新你​​的模特属性            bindingContext.Model = yourModel;
            //返回true ||假如果绑定成功
        }

请确保您使用的类和接口的WebAPI,而不是MVC。一些名字是一样的,但不同的命名空间和DLL

So it seems like several people (like here and here) have had issues with MVC4 model binding for ApiControllers, but none of them seem to quite address the issue I'm seeing.

All I'd really like to do is change the array binding behavior for lists of integers. So say I had a request type like this:

public class MyRequestModel
{
    public List<long> ListOfIntegers { get; set; }

    ...
}

And an API GET method like this:

public ResultsResponseModel Get(MyRequestModel request)
{
    // use request.ListOfIntegers meaningfully

    ...

    return response;
}

I basically want to be able to say /api/results/?listOfIntegers=1+2+3+4+5 and have that resolve to the List<long> property.

I've tried my usual model binding tricks, but as with most of the Web API in MVC4 it appears to have a totally separate path for model binding.

The furthest I've gotten is using a System.Web.Http.ModelBinding.ModelBinder attribute on MyRequestModel, and creating a model binder that "implemented" System.Web.Http.ModelBinding.IModelBinder. That consistently yields an object reference exception with stack traces that never touch my code.

Anyone hit this? Have thoughts on what to try next?

UPDATE: Here's a stack trace that I've captured in my custom ExceptionFilterAttribute:

Object reference not set to an instance of an object.
    at System.Web.Http.ModelBinding.DefaultActionValueBinder.BindParameterValue(HttpActionContext actionContext, HttpParameterBinding parameterBinding)
    at System.Web.Http.ModelBinding.DefaultActionValueBinder.<>c__DisplayClass1.BindValuesAsync>b__0(RequestContentReadKind contentReadKind)
    at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass38.<ToAsyncVoidTask>b__37()
    at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)

解决方案

If you're talking ApiControllers, then you're trying to model bind in Web API and now MVC Here's a sample model binder

  public class MyRequestModelBinderProvider : ModelBinderProvider
    {
        MyRequestModelBinder binder = new MyRequestModelBinder();
        public IdeaModelBinderProvider()
        {          
        }

        public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(MyRequestModel))
            {
                return binder;
            }

            return null;
        }
    } 

Here's an example of registering a custom model binder provider

 IEnumerable<object> modelBinderProviderServices = GlobalConfiguration.Configuration.ServiceResolver.GetServices(typeof(ModelBinderProvider));
 List<Object> services = new List<object>(modelBinderProviderServices);
 services.Add(new MyRequestModelBinderProvider());
 GlobalConfiguration.Configuration.ServiceResolver.SetServices(typeof(ModelBinderProvider), services.ToArray());

Now in your custom model binder you use the contexts to access the querystring values

  public class MyRequestModelBinder :  IModelBinder
    {
        public MyRequestModelBinder()
        {

        }

        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            MyRequestModel yourModel; 
            //use contexts to access query string values
            //create / update your model properties

            bindingContext.Model = yourModel;  
            //return true || false if binding is successful
        }

Make sure your using the classes and interfaces for WebAPI and not MVC. Some of the names are the same, but different namespaces and dlls

这篇关于我如何可以调用MVC4自定义模型绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆