网页API路由 - API / {控制器} / {行动} / {ID}"功能障碍" API / {控制器} / {ID} [英] Web API Routing - api/{controller}/{action}/{id} "dysfunctions" api/{controller}/{id}

查看:134
本文介绍了网页API路由 - API / {控制器} / {行动} / {ID}"功能障碍" API / {控制器} / {ID}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Global.asax中的默认路由:

I have the default Route in Global.asax:

 RouteTable.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{id}",
         defaults: new { id = System.Web.Http.RouteParameter.Optional }
         );

我想成为能够针对特定的功能,所以我创建了另一条路线:

I wanted to be able to target a specific function, so I created another route:

RouteTable.Routes.MapHttpRoute(
         name: "WithActionApi",
         routeTemplate: "api/{controller}/{action}/{id}",
         defaults: new { id = System.Web.Http.RouteParameter.Optional }
         );

所以,在我的控制器,我有:

So, in my controller, I have:

    public string Get(int id)
    {
        return "object of id id";
    }        

    [HttpGet]
    public IEnumerable<string> ByCategoryId(int id)
    {
        return new string[] { "byCategory1", "byCategory2" };
    }

呼叫... / API /记录/ bycategoryid / 5将会给我我想要的。
但是,调用... / API /记录/ 1会给我的错误,发现多个操作符合要求,即:......。

Calling .../api/records/bycategoryid/5 will give me what I want. However, calling .../api/records/1 will give me the error "Multiple actions were found that match the request: ...".

我明白这是为什么 - 路由只是定义什么的URL是有效的,但是当涉及到​​的功能匹配,都得到(INT ID)和ByCategoryId(INT ID)匹配API / {控制器} / {ID},其中是什么迷的框架。

I understand why that is - the routes just define what urls are valid, but when it comes to function matching, both Get(int id) and ByCategoryId(int id) match api/{controller}/{id}, which is what "confuses" the framework.

什么我需要做的就是默认路由API重新工作,并保持一个与{}行动?我想创建一个名为RecordByCategoryIdController相匹配的缺省路由API不同的控制器,为此,我会要求... / API / recordbycategoryid / 5。不过,我觉得这是一个脏(因此不理想)解决方案。我看了关于这个答案,并没有教程在那里使用具有{}行动甚至提到这个问题的途径。

What do I need to do to get the default API route to work again, and keep the one with {action}? I thought of creating a different controller named RecordByCategoryIdController to match the default API route, for which I would request .../api/recordbycategoryid/5. However, I find that to be a "dirty" (thus unsatisfactory) solution. I've looked for answers on this and no tutorial out there on using a route with {action} even mentions this issue.

推荐答案

路由引擎使用您添加​​到规则用同样的顺序。一旦它获得的第一个匹配的规则,它就会停止检查其他规则,并借此寻找控制器和操作。

The route engine uses the same sequence as you add rules into it. Once it gets the first matched rule, it will stop checking other rules and take this to search for controller and action.

所以,你应该:


  1. 把你的具体规则超前的一般规则(如默认值),这意味着使用 RouteTable.Routes.MapHttpRoute 映射WithActionApi,然后再 DefaultApi。

  1. Put your specific rules ahead of your general rules(like default), which means use RouteTable.Routes.MapHttpRoute to map "WithActionApi" first, then "DefaultApi".

删除默认值:你的WithActionApi规则的新{ID = System.Web.Http.RouteParameter.Optional} 参数,因为一旦ID是可选的,像/ API / {1部分} / {}第2部分URL永远不会进入DefaultApi。

Remove the defaults: new { id = System.Web.Http.RouteParameter.Optional } parameter of your "WithActionApi" rule because once id is optional, url like "/api/{part1}/{part2}" will never goes into "DefaultApi".

一个名为动作添加到您的DefaultApi告诉路线引擎动作输入。否则,一旦你在你的控制器不止一个动作,发动机将无法知道使用哪一个,并抛出多的行动中发现符合要求,即:......。然后使它的GET方法匹配,使用<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.mvc.actionnameattribute%28v=vs.108%29.aspx\">ActionNameAttribute.

Add an named action to your "DefaultApi" to tell the route engine which action to enter. Otherwise once you have more than one actions in your controller, the engine won't know which one to use and throws "Multiple actions were found that match the request: ...". Then to make it matches your Get method, use an ActionNameAttribute.

所以,你的路线应该是这样的:

So your route should like this:

// Map this rule first
RouteTable.Routes.MapRoute(
     "WithActionApi",
     "api/{controller}/{action}/{id}"
 );

RouteTable.Routes.MapRoute(
    "DefaultApi",
    "api/{controller}/{id}",
    new { action="DefaultAction", id = System.Web.Http.RouteParameter.Optional }
);

和控制器:

[ActionName("DefaultAction")] //Map Action and you can name your method with any text
public string Get(int id)
{
    return "object of id id";
}        

[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
    return new string[] { "byCategory1", "byCategory2" };
}

这篇关于网页API路由 - API / {控制器} / {行动} / {ID}&QUOT;功能障碍&QUOT; API / {控制器} / {ID}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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