問題描述
我需要一個(gè)自定義的 IHttpControllerSelector
,它應(yīng)該只應(yīng)用于特定的路由.所有其他 web api 路由應(yīng)使用 IHttpControllerSelector
的默認(rèn)實(shí)現(xiàn).
I need a custom IHttpControllerSelector
which should be applied to a specific route only. All other web api routes should use the default implementation of IHttpControllerSelector
.
在研究時(shí),我發(fā)現(xiàn)以下代碼旨在在應(yīng)用程序啟動(dòng)時(shí)替換 IHttpControllerSelector,但它完全替換了默認(rèn)控制器選擇器,這導(dǎo)致應(yīng)用程序中的所有路由都使用我的自定義控制器選擇器:
While researching I found the following code that is meant to replace the IHttpControllerSelector at application start, but it replaces the default controller selector completely, which causes that all routes in the application use my custom controller selector:
config.Services.Replace(typeof(IHttpControllerSelector),
new CustomControllerSelector(config));
有沒有辦法為單個(gè)路由配置 IHttpControllerSelector
?
Is there a way to configure the IHttpControllerSelector
for a single route?
推薦答案
您可以將每個(gè)路由消息處理程序分配給需要使用不同控制器選擇邏輯的路由.此處理程序?qū)?biāo)記 HttpRequestMessage
與此請求需要區(qū)別對待的標(biāo)志.
You can assign a per-route message handler to the route that needs to use a different controller selection logic. This handler would mark the HttpRequestMessage
with a flag that this request needs to be treated differently.
然后簡單地使 CustomControllerSelector
從 DefaultHttpControllerSelector
繼承并檢查該標(biāo)志:
Then simply make the CustomControllerSelector
inherit from DefaultHttpControllerSelector
and inspect that flag:
- 如果已設(shè)置,請繼續(xù)使用您的自定義邏輯
- 如果沒有設(shè)置,返回base(
DefaultHttpControllerSelector
)
代碼如下:
1) 消息處理程序,設(shè)置標(biāo)志
1) message handler, setting the flag
public class RouteSpecificHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Properties["UseCustomSelector"] = true;
return base.SendAsync(request, cancellationToken);
}
}
2) 僅將每個(gè)路由消息處理程序分配給特定路由(不要為其他路由運(yùn)行)
2) assigning per route message handler to the specific route only (do not run for other routes)
config.Routes.MapHttpRoute(
name: "MyRoute",
routeTemplate: "api/dummy/{id}",
defaults: new {controller = "Dummy", id = RouteParameter.Optional},
constraints: null,
handler: new RouteSpecificHandler { InnerHandler = new HttpControllerDispatcher(config) }
);
3) 尊重標(biāo)志的自定義選擇器:
3) custom selector respecting the flag:
public class CustomSelector : DefaultHttpControllerSelector
{
public CustomSelector(HttpConfiguration configuration) : base(configuration)
{
}
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
if (request.Properties.ContainsKey("UseCustomSelector") &&
request.Properties["UseCustomSelector"] as bool? == true)
{
//your logic goes here
}
return base.SelectController(request);
}
}
4) 注冊選擇器:
config.Services.Replace(typeof(IHttpControllerSelector), new CustomSelector(config));
編輯
如果您不希望從 DefaultHttpControllerSelector
繼承 - 然后直接實(shí)現(xiàn) IHttpControllerSelector
,而不是調(diào)用 base.SelectController(request)
保存舊選擇器作為類中的字段/屬性
edit
If you wish to not inherit from DefaultHttpControllerSelector
- then implement IHttpControllerSelector
directly, and instead of calling the base.SelectController(request)
save the old selector as a field/property in your class
public class CustomSelector : IHttpControllerSelector
{
private HttpConfiguration _config;
public IHttpControllerSelector PreviousSelector {get; set;}
public CustomSelector(HttpConfiguration configuration)
{
_config = configuration;
}
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
if (request.Properties.ContainsKey("UseCustomSelector") &&
request.Properties["UseCustomSelector"] as bool? == true)
{
//your logic goes here
}
return PreviousSelector.SelectController(request);
}
}
那就改注冊吧:
var previousSelector = config.Services.GetService(typeof(IHttpControllerSelector)) as IHttpControllerSelector;
config.Services.Replace(typeof(IHttpControllerSelector), new CustomSelector(config) { PreviousSelector = previousSelector});
這篇關(guān)于用于單個(gè)路由的 ASP.NET Web API 自定義 IHttpControllerSelector的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!