2017-12-27 414 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)