我正在尝试通过Startup.cs中的以下代码让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
,则会在Get()
类上运行FooController : Controller
方法。GET http://example.com/api/foo/123
,则会在Get(int id)
课程中运行FooController : Controller
方法。POST http://example.com/api/foo
,则会在Post([FromBody] T postedItem)
课程中运行FooController<T> : Controller
方法。POST http://example.com/api/foo/123
,则会在Post(int id, [FromBody] T postedItem)
课程中运行FooController<T> : Controller
方法。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 :(得分:1)
所以我不记得究竟是什么问题,但元解决方案是你可以通过将日志级别从“信息”增加到“调试”来调试路由问题。例如,通过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)