访问在DelegatingHandler中执行的当前控制器

时间:2012-10-20 01:37:59

标签: asp.net asp.net-web-api

我想知道是否可以在DelegatingHandler的SendAsync方法中访问正在执行(或即将执行)的控制器?我似乎无法弄清楚如何访问它,我认为这是因为它在控制器执行之外执行...

可以参考吗?

3 个答案:

答案 0 :(得分:16)

不,因为消息处理程序在原始HttpRequestMessage或原始HttpResponseMessage上运行(如果是连续的话)。实际上,没有“当前控制器执行”DelegatingHandlers的概念,因为在将请求分派给控制器之前将调用消息处理程序,或者(再次,在继续的情况下)控制器返回响应。

但是,这实际上取决于你要做的事情。

如果您想知道请求最终会被路由到哪个控制器,您可以手动调用内部选择控制器的机制。

public class MyHandler : DelegatingHandler
{
    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        var config = GlobalConfiguration.Configuration;
        var controllerSelector = new DefaultHttpControllerSelector(config);

        // descriptor here will contain information about the controller to which the request will be routed. If it's null (i.e. controller not found), it will throw an exception
        var descriptor = controllerSelector.SelectController(request);

        // continue
        return base.SendAsync(request, cancellationToken);
    }
}

答案 1 :(得分:2)

扩展@GalacticBoy解决方案,最好使用

public class MyHandler : DelegatingHandler
{
    private static IHttpControllerSelector _controllerSelector = null;

    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        if (_controllerSelector == null)
        {
            var config = request.GetConfiguration();
            _controllerSelector = config.Services.GetService(typeof(IHttpControllerSelector)) as IHttpControllerSelector;
        }

        try
        {
            // descriptor here will contain information about the controller to which the request will be routed. If it's null (i.e. controller not found), it will throw an exception
            var descriptor = _controllerSelector.SelectController(request);


        }
        catch
        {
            // controller not found
        }

        // continue
        return base.SendAsync(request, cancellationToken);
    }
}

答案 2 :(得分:0)

根据您对信息的处理情况,您可以在执行请求后获取信息。例如,记录执行的控制器/操作。

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace Example
{
    public class SampleHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return base.SendAsync(request, cancellationToken)
                       .ContinueWith(task =>
                       {
                           HttpResponseMessage response = task.Result;

                           string actionName = request.GetActionDescriptor().ActionName;
                           string controllerName = request.GetActionDescriptor().ControllerDescriptor.ControllerName;

                            // log action/controller or do something else

                           return response;
                       }, cancellationToken);
        }
    }
}