【问题标题】:Route action based on HTTP verb?基于 HTTP 动词的路由操作?
【发布时间】:2018-01-09 06:40:40
【问题描述】:

我正在尝试让 ASP.NET Core 2 MVC 通过 Startup.cs 中的以下代码基于 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,则在我的FooController : Controller 上运行Delete(int id) 方法

当我运行该项目时,它似乎没有运行我的任何控制器。我有一些响应的 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

【问题讨论】:

  • 什么是FooController<T>?您不能直接路由到通用控制器,因为 Core 在构造期间无法提供类型。您可以将其用作基本控制器,但您必须路由到“实现”该类型的东西,即BarController : FooControlller<Bar>
  • @ChrisPratt:这是一段伪代码,旨在传达各种控制器将期望不同的 POST 正文模式并接收各自类型的 [FromBody] 参数。我绝对可以将具体类型作为方法参数 - 只是每个类将具有相同的方法名称但期望不同的具体类型。附言我喜欢你的电影(也许你真的是 Chris Pratt?):youtube.com/embed/kj802AGE9Bg?start=22&end=25

标签: asp.net-core-mvc


【解决方案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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-25
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 2021-10-13
    相关资源
    最近更新 更多