的WebAPI路由与整型数组和行动 [英] Webapi Routing with Integer array and Actions

查看:251
本文介绍了的WebAPI路由与整型数组和行动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这问题我发疯。

我有一个get方法,该方法ID阵列定制ModelBinder的(我可以调用 HTTP: //xckvjl.com/api/results/1,23,34 ,)

I have a get method that takes ID array with custom ModelBinder (I can call http://xckvjl.com/api/results/1,23,34,)

我要介绍的获取上行动。 (这样我可以称呼其为 http://alskjdfasl.com/api/results/latest

I want to introduce Gets on actions. (so that I can call as http://alskjdfasl.com/api/results/latest)

我有以下网页API路由。

I have the following web api routing.

config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional });

config.Routes.MapHttpRoute("ApiWithAction", "{controller}/{action}");

我试图用(请注意这里我用我的自定义模型粘合剂)

I have tried with (Please note here that I am using my custom model binder)

config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional }, new {id = @"\d+" });

您可以重现此错误与此示例:

You can reproduce this error with this sample:

public class TestController: ApiController {

          [HttpGet]
           public virtual IHttpActionResult Get([ModelBinder(typeof(CommaDelimitedCollectionModelBinder))]IEnumerable<int> id = null )
        { }

          [HttpGet]
           public virtual IHttpActionResult Latest( )
        { }

}

 public class CommaDelimitedCollectionModelBinder : IModelBinder
    {
        public bool BindModel(HttpActionContext actionContext,
            ModelBindingContext bindingContext)
        {
            var key = bindingContext.ModelName;
            var val = bindingContext.ValueProvider.GetValue(key);

            if (val == null)
            {
                return false;
            }

            var s = val.AttemptedValue;
            if (s != null && s.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Length > 0)
            {
                var array = s.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select( n=>Convert.ToInt32(n)).ToArray();
                Type type = bindingContext.ModelType.GetGenericArguments().First();

                var typeValue = Array.CreateInstance(type, array.Length);
                array.CopyTo(typeValue, 0);

                bindingContext.Model = array;
            }
            else
            {
                bindingContext.Model = new[] { s };
            }

            return true;
        }
    }

如果我写的是:

[HttpGet]
[Route("Tests/latest")]
 public virtual IHttpActionResult Latest( )
        { }

它的工作原理。不过,我想全球范围内的路由。否则,对于每一个动作,我将不得不写相同的。

It works. However, I want global level routing. Otherwise for every action I will have to write the same.

请指教。

推荐答案

所以这里的dilimma:

So here's the dilimma:

通过这条路线的定义:

config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional });

当你调用 http://alskjdfasl.com/api/results/latest 最新的变成值的 ID ,这显然会引发错误,因为不能将字符串转换为 INT 阵列。

when you call http://alskjdfasl.com/api/results/latest, latest becomes the value of id, which obviously will throw error since string cannot be converted to int array.

添加此路由定义

config.Routes.MapHttpRoute("ApiWithAction", "{controller}/{action}"); 

不会帮助,因为现在你要么必须处理订单或定义目前已被屏蔽,由于这个你其他行动路线。

won't help since now you either have to deal with order or define routes for your other actions which are now being masked due to this.

不宣而在个人层面上的路线,唯一的其他选择,使不同的模板,或者创建能理解阵列自己的路由约束。

Without declaring routes at individual level, the only other options are to make the templates different or create your own route constraint that understands arrays.

我首先给这些一枪:

config.Routes.MapHttpRoute("ApiWithAction", "{controller}/{action}/{id}", new { id = RouteParameter.Optional });

// or if all your methods are called latest

config.Routes.MapHttpRoute("ApiWithAction", "{controller}/latest");

如果实在不行,我会说去与属性的路由。他们是清洁的。

If nothing works, I would say go with attribute routes. They are cleaner.

这篇关于的WebAPI路由与整型数组和行动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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