我有以下几点:

  • 请求url:'endpoint/1,2,3?q = foo'
  • 请求绑定(bind)到的
  • 操作:
    公共(public)对象Bar([ModelBinder] List ids,[FromUri]字符串q)

  • 我想将“1,2,3”片段映射到“ids”参数,因此我根据this link创建了ModelBinderProvider,应该调用适当的模型绑定(bind)器。
    public class MyModelBinderProvider: ModelBinderProvider
    {
        public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)
        {
            IModelBinder modelBinder = null;
    
            if (modelType.IsGenericType && (modelType.GetGenericTypeDefinition() == typeof(List<>)))
            {
                modelBinder = new ListModelBinder();
            }
    
            return modelBinder;
        }
    }
    

    我像这样在Global.asax中注册了提供程序:
    GlobalConfiguration.Configuration.Services.Insert(typeof(ModelBinderProvider), 0, new MyModelBinderProvider());
    

    的原因:我创建此提供程序的原因是,无论T是什么('1,2,3'或'one,two,3'),我都希望绑定(bind)能够正常工作。

    问题:
    假设T为'int';每次发送请求时,“modelType”参数始终为“int”,而不是我期望的值-“List ”,因此未正确处理请求。

    奇怪的事情:这样做是可行的,但是T是专门的,因此不是我想要的:
    var simpleProvider = new SimpleModelBinderProvider(typeof(List<int>), new ListModelBinder());
    GlobalConfiguration.Configuration.Services.Insert(typeof(ModelBinderProvider), 0, simpleProvider);
    

    我看不到我在做什么错,为什么'modelType'参数不是期望值?

    最佳答案

    这是一个很老的问题,但是我在这里有一个类似的遗留代码问题。

    保留了逗号,尽管在某些情况下可以使用逗号,但是应该避免使用,但是如果您真的想使用它们...

    我认为,一旦“1、2、3”是网址的路径部分,则比模型绑定(bind)器更多的是路径问题。假设这是我写的一个小的RouteHandler可以解决的(请原谅非常简单的“单词到整数”转换器)。

    CsvRouteHandler从URL获取id数组,并将其作为整数数组放在RouteData上。如果原始数组包含诸如一,二或三的单词,则它将每个值转换为int。

    MvcRouteHandler

    protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext)
    {
        var idArrayParameter = requestContext.RouteData.Values["idArray"] != null ? requestContext.RouteData.Values["idArray"].ToString() : null;
        if (string.IsNullOrEmpty(idArrayParameter))
        {
            return base.GetHttpHandler(requestContext);
        }
    
        requestContext.RouteData.Values.Remove("idArray"); // remove the old array from routedata
    
        // Note: it is horrible and bugged but and you probably have your own translation method :)
        string[] idArray = idArrayParameter.Split(',');
        int[] ids = new int[idArray.Length];
    
        for(int i = 0; i < idArray.Length; i++)
        {
            if (!int.TryParse(idArray[i], out ids[i]))
            {
                switch (idArray[i])
                {
                    case "one":
                        ids[i] = 1;
                        break;
                    case "two":
                        ids[i] = 2;
                        break;
                    case "three":
                        ids[i] = 3;
                        break;
                }
            }
        }
    
        requestContext.RouteData.Values.Add("Id", ids);
    
        return base.GetHttpHandler(requestContext);
    
    }
    }
    

    路由配置:
        routes.Add(
            name: "Id Array Route",
            item: new Route(
                url: "endpoint/{idArray}",
                defaults: new RouteValueDictionary(new { controller = "Test", action = "Index" }),
                routeHandler: new CsvRouteHandler())
        );
    

    关于asp.net - C#Web API模型绑定(bind)程序提供程序应如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24470039/

    10-17 02:24