asp.net-web-apiasp.net-web-api2message-handlers

Remove/add MessageHandlers at runtime


How can I add or remove message handlers at runtime? The following example does not work:

var logHandler = GlobalConfiguration.Configuration.MessageHandlers.FirstOrDefault(a => a.GetType() == typeof(ApiLogHandler));

if (logHandler == null)
{
    GlobalConfiguration.Configuration.MessageHandlers.Add(new ApiLogHandler());
}
else
{
    GlobalConfiguration.Configuration.MessageHandlers.Remove(logHandler);
}

The message handler is added to the list, but it is not called in the the next requests...


Solution

  • I would inject a MessageHandler into the configuration at startup that is built specifically to have a dynamic list of inner message handlers, and change the interface they use from DelegatingHandler to a custom one, e.g.

    public interface ICustomMessageHandler 
    {
        Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
    }
    

    After this, you can create a standard MessageHandler that contains a list of inner handlers:

    public class DynamicMessageHandler : DelegatingHandler
    {
        public List<ICustomMessageHandler> InnerHandlers { get; set; }
    
        public DynamicMessageHandler()
        {
            InnerHandlers = new List<ICustomMessageHandler>();
        }
    
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            foreach (var innerHandler in InnerHandlers)
            {
                await innerHandler.SendAsync(request, cancellationToken);
            }
    
            return await base.SendAsync(request, cancellationToken);
        }
    }
    

    This way youshould be able to modify the list of InnerHandlers at runtime as long as you keep a single instance of DynamicMessageHandler around.