2017-12-27 916 views
0

我想基于在Startup.cs通过下面的代码HTTP动词得到ASP.NET的Core 2 MVC路由的行动:基于HTTP动词的路由动作?

 app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "post", 
       template: "api/{controller}/{id?}", 
       defaults: new { action = "Post" }, 
       constraints: new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint("POST") }) 
      ); 
      routes.MapRoute(
       name: "delete", 
       template: "api/{controller}/{id?}", 
       defaults: new { action = "Delete" }, 
       constraints: new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint("DELETE") }) 
      ); 
      routes.MapRoute(
       name: "default", 
       template: "api/{controller}/{action=Get}/{id?}"); 
     }); 

也就是说,

  • 如果客户端请拨打GET http://example.com/api/foo,在我的FooController : Controller类上运行Get()方法。
  • 如果他们呼叫GET http://example.com/api/foo/123,那么在我的FooController : Controller类上运行Get(int id)方法。
  • 如果他们呼叫POST http://example.com/api/foo,那么在我的FooController<T> : Controller类上运行Post([FromBody] T postedItem)方法。
  • 如果他们呼叫POST http://example.com/api/foo/123,那么在我的FooController<T> : Controller类上运行Post(int id, [FromBody] T postedItem)方法。
  • 如果他们叫DELETE http://example.com/api/foo/123,在运行Delete(int id)方法对我FooController : Controller

当我运行该项目,它似乎并没有运行任何我的控制器。我有一些Razor页面可以响应,但所有基于控制器的路由只返回404路由。即使默认路由似乎不起作用。

我一直在使用https://github.com/ardalis/AspNetCoreRouteDebugger试图帮助我缩小问题的范围,但我仍然没有发现问题。它将控制器上的方法显示为可用操作,但未列出通过MapRoute添加的任何名称,模板或约束。我很高兴知道任何其他有用的工具。

FWIW,我试图使用相同的动词限制如下: https://github.com/aspnet/Routing/blob/2.0.1/src/Microsoft.AspNetCore.Routing/RequestDelegateRouteBuilderExtensions.cs#L252-L268

+0

什么是'FooController的'?您无法直接路由到通用控制器,因为Core在构建期间无法提供该类型。您可以将其用作基本控制器,但您必须路由到“实现”该类型的内容,即“BarController:FooControlller '。 –

+0

@ChrisPratt:这是一些伪代码,旨在传达各种控制器将期望不同的POST主体架构并接收各自类型的[FromBody]参数。我把把具体类型作为方法参数一定没问题 - 只是每个类都有相同的方法名称,但期望不同的具体类型。附:我喜欢你的电影(也许你真的是克里斯普拉特?):https://www.youtube.com/embed/kj802AGE9Bg?start=22&end=25 – steamer25

回答

0

所以我不记得到底是什么问题原来是,但元的解决方案是,你可以调试路由通过将日志级别从“信息”增加到“调试”来解决问题。例如,通过appsettings.json:

{ 
    "Logging": { 
    "Debug": { 
     "LogLevel": { 
     "Default": "Debug" 
     } 
    }, 
    "Console": { 
     "LogLevel": { 
     "Default": "Debug" 
     } 
    } 
    } 
} 

...然后你会得到这样的例如,Visual Studio中的应用程序输出窗格中的消息:

[40m[37mdbug[39m[22m[49m: Microsoft.AspNetCore.Routing.RouteConstraintMatcher[1] 
     Route value '(null)' with key 'httpMethod' did not match the constraint 'Microsoft.AspNetCore.Routing.Constraints.HttpMethodRouteConstraint'. 
Microsoft.AspNetCore.Routing.RouteConstraintMatcher:Debug: Route value '(null)' with key 'httpMethod' did not match the constraint 'Microsoft.AspNetCore.Routing.Constraints.HttpMethodRouteConstraint'. 
[40m[37mdbug[39m[22m[49m: Microsoft.AspNetCore.Routing.RouteBase[1] 
     Request successfully matched the route with name 'get' and template 'api/{controller}/{id?}'. 
Microsoft.AspNetCore.Routing.RouteBase:Debug: Request successfully matched the route with name 'get' and template 'api/{controller}/{id?}'. 
[40m[37mdbug[39m[22m[49m: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1] 
     Executing action Contoso.Media.ServiceHost.Controllers.MediaController.Get (Contoso.Media.ServiceHost) 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Debug: Executing action Contoso.Media.ServiceHost.Controllers.MediaController.Get (Contoso.Media.ServiceHost)