Asp.net web api 动态添加消息处理程序

Asp.net web api 动态添加消息处理程序,asp.net-web-api,Asp.net Web Api,我有四个消息处理程序——MyHandler、MyHandler1、MyHandler2和MyOtherHandler。我已将MyHandler和MyOtherHandler添加到handlers集合中,但没有添加MyHandler1或MyHandler2 config.MessageHandlers.Add(new MyHandler()); config.MessageHandlers.Add(new MyOtherHandler()); 我希望MyHandler1或MyHandler2由M

我有四个消息处理程序——MyHandler、MyHandler1、MyHandler2和MyOtherHandler。我已将MyHandler和MyOtherHandler添加到handlers集合中,但没有添加MyHandler1或MyHandler2

config.MessageHandlers.Add(new MyHandler());
config.MessageHandlers.Add(new MyOtherHandler());
我希望MyHandler1或MyHandler2由MyHandler动态添加到管道中,具体取决于某些条件。我知道MyHandler1和MyHandler2可以添加到config.MessageHandlers集合中,当轮到它们时,当“some”条件不适用时,它们什么也不做,但这不是我想要的。假设我有大约100个这样的处理程序,我不希望所有这些处理程序都在管道中运行,但只有当我的处理程序认为这是合适的时候

我无法通过设置MyHandler.InnerHandler将MyHandler1手动插入管道。该链对所有请求进行全局缓存,我无法对与特定请求相关的内容进行修改。这就是我所做的

我创建了一个基本处理程序,它增加了SendAsync的可见性

public abstract class MyBaseHandler : DelegatingHandler
{

    public Task<HttpResponseMessage> WrapperSendAsync(
                                    HttpRequestMessage request,
                                        CancellationToken cancellationToken)
    {
        return this.SendAsync(request, cancellationToken);
    }
}
公共抽象类MyBaseHandler:DelegatingHandler
{
公共任务包装器SendAsync(
HttpRequestMessage请求,
取消令牌(取消令牌)
{
返回此.SendAsync(请求、取消令牌);
}
}
我从这个基础上导出了MyHandler1和MyHandler2

public class MyHandler1 : MyBaseHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                                    HttpRequestMessage request,
                                        CancellationToken cancellationToken)
    {
        // Use request

        var response = await base.SendAsync(request, cancellationToken);

        // Use response

        return response;

    }
}
公共类MyHandler1:MyBaseHandler
{
受保护的异步覆盖任务SendAsync(
HttpRequestMessage请求,
取消令牌(取消令牌)
{
//使用请求
var response=await base.sendaync(请求、取消令牌);
//使用响应
返回响应;
}
}
现在,MyHandler可以根据条件实例化MyHandler1或Myhandler2,并将InnerHandler设置为自己的InnerHandler,只需通过包装器调用并返回SendAsync即可

public class MyHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                                    HttpRequestMessage request,
                                        CancellationToken cancellationToken)
    {
        // Check condition and choose MyHandler1 or MyHandler2 or just return
        // await base.SendAsync(request, cancellationToken);
        var h = new MyHandler1();
        h.InnerHandler = this.InnerHandler;
        return await h.WrapperSendAsync(request, cancellationToken);

        // When MyHandler1 and MyHandler2 is no good, I just want
        // to do nothing and let the other handlers do their job
        // return await base.SendAsync(request, cancellationToken);

    }
}
公共类MyHandler:DelegatingHandler
{
受保护的异步覆盖任务SendAsync(
HttpRequestMessage请求,
取消令牌(取消令牌)
{
//检查条件并选择MyHandler1或MyHandler2或仅返回
//wait base.sendaync(请求、取消令牌);
var h=新的MyHandler1();
h、 InnerHandler=this.InnerHandler;
return wait h.WrapperSendAsync(请求、取消令牌);
//当MyHandler1和MyHandler2不好的时候,我只想
//什么也不做,让其他处理者做他们的工作
//返回wait base.sendaync(请求、取消令牌);
}
}

它确实有效,但我不确定这样做是否会破坏某些东西。我采用这种方法是否忽略了什么?

你的方法看起来不错。我很确定它应该可以正常工作。

也许你应该检查一些东西,比如跟踪和CORS。当启用跟踪并接收到第一个请求时,配置初始化,配置上的消息处理程序由跟踪消息处理程序包装,并且如果启用CORS,则CORS消息处理程序将添加到消息处理程序列表的末尾。谢谢,Kiran。启用跟踪后,它仍然可以工作,但对于动态添加到管道中的处理程序,System.Web.Http.tracing.Tracers.MessageHandlerTracer不会创建跟踪条目(“SendAsync”)。不过我还没有测试CORS。由于您将此添加为评论,我无法将其标记为答案,我只能对您的评论进行投票。我已经接受了优素福的答复。毕竟你们都为MSFT工作:)Badri,这意味着你们将无法跟踪正在添加的动态消息处理程序。对你来说可能没问题。CORS应该可以正常工作。