网络API路线被忽略和MVC处理 [英] Web API route is ignored and processed by MVC

查看:175
本文介绍了网络API路线被忽略和MVC处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想不通为什么一个途径是由MVC处理,而不是网络的API。

I can't figure out why a route is being processed by MVC instead of Web API.

整条线路的配置如下:

configuration.Routes.MapHttpRoute
(
    name: "AdminControllers.TicketingController",
    routeTemplate: "api/company/tickets",
    defaults: new 
    { 
        controller = "Ticketing", 
        id = RouteParameter.Optional, 
        action = "GetTickets" 
    }
);

和API的控制器看起来是这样的:

And the API controller looks like this:

public sealed class TicketingController : ApiController
{
    [HttpGet]
    public HttpResponseMessage GetTickets()
    {
        return ControllerContext.Request.CreateResponse(HttpStatusCode.OK);
    }
}

我进行HTTP / GET请求 / API /公司/门票,我得到了以下错误:

I perform a HTTP/GET request to /api/company/tickets and I get the following error:

该控制器路径/ API /公司/票不   发现或没有实现IController。

The controller for path "/api/company/tickets" was not found or does not implement IController.

异常的堆栈跟踪指向ASP.NET MVC(不是Web API): System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext中的RequestContext,类型controllerType)

Exception's stack trace points to ASP.NET MVC (not Web API): System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType).

AFAIK,这发生在你使用了错误的框架,而不是网络API HttpConfiguration.Routes.MapHttpRoute 扩展方法(MVC)地图的路线。在我的示例上面,你发现会发现我使用正确的资源来注册的Web API控制器。

AFAIK, this happens when you map a route using the wrong framework (MVC) instead of Web API HttpConfiguration.Routes.MapHttpRoute extension method. In my sample found above you'll find I'm using the right resource to register a controller in Web API.

我可以证实,路线得到在应用程序启动时注册。

I can confirm that the route gets registered during application startup.

现在的问题是ASP.NET MVC管道处理的路线,显然,它并没有找到控制器整条线路。

The problem is ASP.NET MVC pipeline handles the route and, obviously, it does find no controller for the whole route.

我在做什么错在这里?

请注意:这是的ASP.NET Web API 1.x和我不能使用的Web API 2.0(我喜欢使用属性的路由,是啊)

NOTE: It's ASP.NET Web API 1.x and I can't use Web API 2.0 (I would love to use attribute routing, yeah).

相信与否,但它开始工作时,我改变路由配置为​​:

Believe or not, but it started to work when I changed route configuration to:

configuration.Routes.MapHttpRoute(
    name: "AdminControllers.TicketingController",
    routeTemplate: "api/company/tickets/{id}",
    defaults: new 
    { 
        controller = "Ticketing", 
        id = RouteParameter.Optional, 
        action = "GetTickets" 
    }
);

和Web API操作更改为:

And Web API action changed to:

[HttpGet]
public HttpResponseMessage GetTickets(int? id)
{
    return ControllerContext.Request.CreateResponse(HttpStatusCode.OK);
}

这似乎是一个路由参数,使不同的,足以通过MVC被忽略,然后通过网络API管道处理的路线。但我可以证实,有以API /公司/".

It seems like a route parameter makes the route different enough to be ignored by MVC and then processed by Web API pipeline. But I can confirm that there's no other route starting with "api/company/".

总之,它的工作原理,如果我给 ID (FE / API /公司/票/ 11 )。否则,MVC管道工艺路线......

Anyway, it works if I give the id (f.e. /api/company/tickets/11). Otherwise, MVC pipeline processes the route...

推荐答案

在寻找解决办法,我已经有了一个正在运行的。

After looking for solutions, I've got a working one.

首先,我在部署Web API控制器到Windows Azure包管理员的网站(AdminSite)。它是由在ASP.NET MVC 4.0。无论如何,我相信我的答案应该有道理的,如果你发现了同样的问题,我将描述在任何ASP.NET MVC和Web API的混合应用。

First of all, I'm deploying a Web API controller to Windows Azure Pack administrator's site (AdminSite). It's made with ASP.NET MVC 4.0. Anyway, I believe my answer should make sense if you find the same problem I'm going to describe in any ASP.NET MVC and Web API mixed application.

是的,因为它是可以适应的Web API控制器URI方案的URL路径... *

目前的一天结束,这是解决把网络API的路由之前的MVC的。这样一来,ASP.NET将请求路由到一些URI路径模式的第一个巧合:

At the end of the day, this is solved putting Web API routes before MVC ones. This way, ASP.NET will route requests to the first coincidence of some URI route pattern:

// #1 we add the whole routes. One for listing, other for getting
// a single entity (ticket)
configuration.Routes.MapHttpRoute(
    name: "Company.AzurePack.Ticketing.List",
    routeTemplate: "api/company/tickets",
    defaults: new
    {
        controller = "Ticketing",
        action = "GetTickets"
    }
);

configuration.Routes.MapHttpRoute(
    name: "Company.AzurePack.Ticketing.GetOne",
    routeTemplate: "api/company/tickets/{id}",
    defaults: new 
    { 
        controller = "Ticketing", 
        action = "GetTicket" 
    }
);

// #2 we get both added routes from the route table and we create two
// references to them. Later, we remove and re-insert them at the top
// of route table. BINGO!
RouteBase apiRoute1 = RouteTable.Routes[RouteTable.Routes.Count - 1];
RouteBase apiRoute2 = RouteTable.Routes[RouteTable.Routes.Count - 2];
RouteTable.Routes.Remove(apiRoute1);
RouteTable.Routes.Remove(apiRoute2);

RouteTable.Routes.Insert(0, apiRoute1);
RouteTable.Routes.Insert(0, apiRoute2);

等等,网络API路由注册到 GlobalConfiguration.Configuration.Routes 路由表...

是的,但 HttpConfiguration.Routes 注册其航线 RouteTable.Routes 过了,ASP.NET管道工程与 RouteTable.Routes 。即,既MVC和的WebAPI路线都在同一个路由表

Wait, Web API routes are registered into GlobalConfiguration.Configuration.Routes route table...

Yes, but HttpConfiguration.Routes registers its routes in RouteTable.Routes too, and ASP.NET pipeline works with RouteTable.Routes. That is, both MVC and WebAPI routes are in the same route table.

在下面的截图中,你会发现,网络API路由类型的 HttpWebRoute

In the following screenshot, you'll find that Web API routes are of type HttpWebRoute:

现在这些URI被花哨的Web API控制器供应:

Now these URIs are served by the fancy Web API controller:

  • / API /公司/票
  • / API /公司/票/ 11

在我检查这个解决方案是工作,我重构上面的示例code,以扩展方法:

After I checked that this solution was working, I refactored above sample code to an extension method:

public static class HttpRouteCollectionExtensions
{
    public static IHttpRoute MapHttpRouteAt(this HttpRouteCollection routes, int index, string name, string routeTemplate, object defaults = null, object constraints = null, HttpMessageHandler handler = null)
    {
        Contract.Requires(routes != null);

        IHttpRoute route = routes.MapHttpRoute(name, routeTemplate, defaults, constraints, handler);

        RouteBase apiRoute = RouteTable.Routes[RouteTable.Routes.Count - 1];
        RouteTable.Routes.Remove(apiRoute);

        RouteTable.Routes.Insert(index, apiRoute);

        return route;
    }
}

...现在我可以在路由表的顶部添加路线如下:

...and now I'm able to add routes at the top of routing table as follows:

configuration.Routes.MapHttpRouteAt(
    index: 0,
    name: "sampleRoute",
    routeTemplate: "api/some/path/{name}",
    defaults: new
    {
        controller = "Some",
        action = "SomeAction",
        httpMethod = new HttpMethodConstraint("GET")
    }
);

这篇关于网络API路线被忽略和MVC处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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