微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ASP.NET Web API为单个路由定制IHttpControllerSelector

我需要一个自定义的IHttpControllerSelector,它只应用于特定的路由.所有其他Web api路由应使用IHttpControllerSelector的认实现.

在研究时我发现以下代码意味着在应用程序启动时替换IHttpControllerSelector,但它完全替换了认的控制器选择器,这导致应用程序中的所有路由都使用我的自定义控制器选择器:

config.Services.Replace(typeof(IHttpControllerSelector),new CustomControllerSelector(config));

有没有办法为单个路由配置IHttpControllerSelector?

解决方法

您可以为需要使用不同控制器选择逻辑的路由分配每路由消息处理程序.此处理程序将使用标记标记HttpRequestMessage,该标记需要以不同方式处理此请求.

然后只需使CustomControllerSelector继承自DefaultHttpControllerSelector并检查该标志:

>如果已设置,请继续使用自定义逻辑
>如果未设置,则返回base(DefaultHttpControllerSelector)

这是代码

1)消息处理程序,设置标志

public class RouteSpecificHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
    {
        request.Properties["UseCustomSelector"] = true;
        return base.SendAsync(request,cancellationToken);
    }
}

2)仅将每个路由消息处理程序分配给特定路由(不要为其他路由运行)

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)尊重旗帜的自定义选择器:

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继承 – 那么直接实现IHttpControllerSelector,而不是调用base.SelectController(request)将旧选择器保存为类中的字段/属性

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});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐