Asp.net 访问在DelegatingHandler中执行的当前控制器
我想知道是否可以在DelegatingHandler的SendAsync方法中访问正在执行(或即将执行)的控制器?我似乎不知道如何访问它,我想这是因为它在控制器执行之外执行Asp.net 访问在DelegatingHandler中执行的当前控制器,asp.net,asp.net-web-api,Asp.net,Asp.net Web Api,我想知道是否可以在DelegatingHandler的SendAsync方法中访问正在执行(或即将执行)的控制器?我似乎不知道如何访问它,我想这是因为它在控制器执行之外执行 是否可以引用它?否,因为消息处理程序对原始HttpRequestMessage或原始HttpResponseMessage进行操作(在继续的情况下)。因此,实际上没有使用delegatinghandler执行“当前控制器”的概念,因为消息处理程序将在将请求分派给控制器之前调用,或者(在继续的情况下)在控制器返回响应之后调用
是否可以引用它?否,因为消息处理程序对原始
HttpRequestMessage
或原始HttpResponseMessage
进行操作(在继续的情况下)。因此,实际上没有使用delegatinghandler
执行“当前控制器”的概念,因为消息处理程序将在将请求分派给控制器之前调用,或者(在继续的情况下)在控制器返回响应之后调用
然而,这实际上取决于你想做什么
如果您想知道请求最终将路由到哪个控制器,可以手动调用内部选择控制器的机制
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);
}
}
公共类MyHandler:DelegatingHandler
{
受保护的重写System.Threading.Tasks.Task SendAsync(HttpRequestMessage请求,System.Threading.CancellationToken CancellationToken)
{
var config=GlobalConfiguration.Configuration;
var controllerSelector=新的默认HttpControllerSelector(配置);
//此处的描述符将包含有关请求将路由到的控制器的信息。如果为null(即未找到控制器),则会引发异常
变量描述符=控制器选择器。选择控制器(请求);
//继续
返回base.sendaync(请求、取消令牌);
}
}
扩展@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);
}
}
公共类MyHandler:DelegatingHandler
{
专用静态IHttpControllerSelector _controllerSelector=null;
受保护的重写System.Threading.Tasks.Task SendAsync(HttpRequestMessage请求,System.Threading.CancellationToken CancellationToken)
{
if(_controllerSelector==null)
{
var config=request.GetConfiguration();
_controllerSelector=config.Services.GetService(typeof(IHttpControllerSelector))作为IHttpControllerSelector;
}
尝试
{
//此处的描述符将包含有关请求将路由到的控制器的信息。如果为null(即未找到控制器),则会引发异常
变量描述符=_controllerSelector.SelectController(请求);
}
抓住
{
//找不到控制器
}
//继续
返回base.sendaync(请求、取消令牌);
}
}
根据您对信息的处理方式,您可以在请求执行后获取信息。例如,记录执行的控制器/操作
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);
}
}
}
使用系统;
使用System.Net.Http;
使用系统线程;
使用System.Threading.Tasks;
使用System.Web;
名称空间示例
{
公共类SampleHandler:DelegatingHandler
{
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
return base.sendaync(请求、取消令牌)
.ContinueWith(任务=>
{
HttpResponseMessage response=task.Result;
string actionName=request.GetActionDescriptor().actionName;
字符串controllerName=request.GetActionDescriptor().ControllerDescriptor.controllerName;
//记录操作/控制器或执行其他操作
返回响应;
},取消令牌);
}
}
}
谢谢,我有一个验证例程,如果能够检查控制器类型,看看它是否定义了自定义属性,那就太好了,这样我就可以避免这个验证例程。这应该使这成为可能。太好了。是的,一旦你抓住了一个HttpControllerDescriptor@FilipW有没有一种“好”的方法可以做到这一点而不引发异常?在源代码中,对SelectController
的调用最终调用了this.\u controllerInfoCache.Value.TryGetValue(controllerName,out controllerDescriptor)
但是\u controllerInfoCache
在Web API 2中不能以任何方式公开访问,最好使用请求.GetConfiguration()
扩展方法,而不是全局配置。配置
参考。如何在此处获取操作名称