如果URL中沒有提供任何操作,似乎Web API有一個內置的默認邏輯來使用HTTP Verb作爲操作名稱。例如,我有這樣的路線:如何修改框架的默認Web API路由?
config.Routes.MapHttpRoute(
name: "DefaultApiController",
routeTemplate: "api/{controller}"
);
這裏是我的操作:
public IEnumerable<Conference> Get()
{
...
}
[ActionName("current")]
public IEnumerable<Conference> GetCurrent()
{
...
}
當我去〜/會議用GET動詞,它會帶你到「獲取()「動作。如果使用POST動詞,它會帶您到「Post([FromBody] Conference value)」動作...等等。有衝突,雖然,當你嘗試到〜/會議/ GetCurrent(即使我有[ActionName(「電流」)]在上面):沒有發現
多個動作相匹配的要求,即: 系統.Collections.Generic.IEnumerable
1[MyApp.Models.Conference] Get() on type MyApp.Api.ConferencesController System.Collections.Generic.IEnumerable
1 [MyApp.Models.Conference] GetCurrent()上型MyApp.Api.ConferencesController
這意味着框架使用StartsWith代替等於確定的默認動作。當匹配動詞與動作時,它也忽略了ActionName屬性。
我的問題是如何使框架的默認動作完全匹配動詞,而不是使用StartsWith邏輯?一個GET動詞只應該匹配一個Get()動作,而不是Get(),GetCurrent()GetPast()等(特別是當它忽略ActionName屬性時)。
編輯 爲了簡單起見,我只顯示了上面的一條路線。如果我顯示所有仍在草稿中的路線,我認爲這可能會有所幫助。我試圖讓一個完全工作的REST API,同時還留出空間添加自己的自定義操作:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApiControllerActionId",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: null,
constraints: new { action = @"^[a-zA-Z]+$", id = @"^\d+$" } // action must start with character
);
config.Routes.MapHttpRoute(
name: "DefaultApiControllerActionName",
routeTemplate: "api/{controller}/{action}/{name}",
defaults: null,
constraints: new { action = @"^[a-zA-Z]+$", name = @"^[a-zA-Z]+$" } // action and name must start with character
);
config.Routes.MapHttpRoute(
name: "DefaultApiControllerId",
routeTemplate: "api/{controller}/{id}",
defaults: null,
constraints: new { id = @"^\d+$" } // id must be all digits
);
config.Routes.MapHttpRoute(
name: "DefaultApiControllerAction",
routeTemplate: "api/{controller}/{action}",
defaults: null,
constraints: new { action = @"^[a-zA-Z]+$" } // action must start with character
);
config.Routes.MapHttpRoute(
name: "DefaultApiController",
routeTemplate: "api/{controller}"
);
UPDATE 看來,增加HTTP動詞約束上幫助:
config.Routes.MapHttpRoute(
name: "DefaultApiControllerGet",
routeTemplate: "api/{controller}",
defaults: new { action = "Get" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
);
config.Routes.MapHttpRoute(
name: "DefaultApiControllerPost",
routeTemplate: "api/{controller}",
defaults: new { action = "Post" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) }
);
config.Routes.MapHttpRoute(
name: "DefaultApiControllerPut",
routeTemplate: "api/{controller}",
defaults: new { action = "Put" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Put) }
);
config.Routes.MapHttpRoute(
name: "DefaultApiControllerDelete",
routeTemplate: "api/{controller}",
defaults: new { action = "Delete" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Delete) }
);
對於REST API,我仍然需要得到〜/會議仍儘管 – Basem
編輯工作:OK,現在你發佈的所有路由,畫面更清晰;) –
真棒文章thx!另外AttributeRouting聽起來很有希望,但似乎Web API性能和緩存功能沒有被利用。 – Basem