如何对自定义DelegatingHandler进行单元测试?我有以下但它抱怨innerHandler未设置.
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://foo.com");
var handler = new FooHandler()
{
InnerHandler = new FooHandler()
};
var invoker = new HttpMessageInvoker(handler);
var result = await invoker.SendAsync(httpRequestMessage, new CancellationToken());
Assert.That(result.Headers.GetValues("some-header").First(), Is.Not.Empty, "");
Run Code Online (Sandbox Code Playgroud) 我们有一个ASP.NET Web Api应用程序,它使用OAuth Bearer Tokens进行身份验证,我们正在尝试实现请求/响应日志记录.
基本上它的工作方式如下:
1.用户向"/ authenticate"发送请求并接收身份验证令牌
2.然后,用户使用此身份验证令牌对暴露的API方法发出请求
对于将请求记录到公开的API方法,我们使用的DelegatingHandler是完全正常的.
但是,DelegatingHandler实现不会捕获对"/ authenticate"的请求.
记录令牌请求是否需要不同的方法?
public abstract class MessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var correlationId = Guid.NewGuid();
var requestInfo = string.Format("{0} {1}", request.Method, request.RequestUri);
var requestContent = await request.Content.ReadAsByteArrayAsync();
var context = ((HttpContextBase)request.Properties["MS_HttpContext"]);
await IncomingMessageAsync(correlationId, request.Method, request.RequestUri, request.Headers, requestContent,
context.Request.UserHostAddress, context.Request.IsAuthenticated, context.User.Identity.Name);
var response = await base.SendAsync(request, cancellationToken);
byte[] responseMessage;
responseMessage = await response.Content.ReadAsByteArrayAsync();
await OutgoingMessageAsync(correlationId, response.StatusCode, response.Headers, responseMessage);
return …Run Code Online (Sandbox Code Playgroud) 由于微软建议的HttpClient创建一次,并在整个项目的生命重用,我不知道如何更新DefaultRequestHeaders时,例如,令牌已过期,需要刷新。
DefaultRequestHeaders更不是线程安全的(据我所知)以及在那里定义的标头列表,由所有潜在的待处理请求共享。Clear()列表和Add()带有新标记的标题似乎不是明智之举。
更准确地说,我不想/不需要为每个请求更改请求标头。仅当我获得 HTTP 401 状态代码时。
我有一个正在运行的 Web API 2.0 localhost:4512,我想拦截对域发出的所有请求,localhost:4512无论它们是否由特定路由处理。例如,我想捕获对localhost:4512/abc.dfsada或的请求localhost:4512/meh/abc.js
我已经使用 DelegatingHandler 尝试过此操作,但不幸的是,这只拦截对处理的路由发出的请求:
public class ProxyHandler : DelegatingHandler
{
private async Task<HttpResponseMessage> RedirectRequest(HttpRequestMessage request, CancellationToken cancellationToken)
{
var redirectLocation = "http://localhost:54957/";
var localPath = request.RequestUri.LocalPath;
var client = new HttpClient();
var clonedRequest = await request.Clone();
clonedRequest.RequestUri = new Uri(redirectLocation + localPath);
return await client.SendAsync(clonedRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return RedirectRequest(request, cancellationToken);
}
}
Run Code Online (Sandbox Code Playgroud)
在 WebConfig.cs 中:
config.MessageHandlers.Add(new ProxyHandler());
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute( …Run Code Online (Sandbox Code Playgroud) 使用 .Net Core 2.2,我使用 HttpClient 来调用 API 以及 Http 消息处理程序。消息处理程序注入IHttpContextAccessor,但该对象有时包含一个HttpContext为空的属性 - 我无法理解为什么它会为空。
这是启动时的服务注册:
services.AddTransient<HttpClientTokenHandler>();
services.AddHttpClient("client", c =>
{
c.BaseAddress = new Uri(options.ApiUrl.TrimEnd('/') + '/');
}).AddHttpMessageHandler<HttpClientTokenHandler>();
services.AddHttpContextAccessor();
Run Code Online (Sandbox Code Playgroud)
以及 HttpContext 有时为 null 的令牌处理程序实现。
public HttpClientTokenHandler(IHttpContextAccessor context)
{
_context = context;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var access_token = await _context.HttpContext.GetTokenAsync(Constants.TokenTypes.AccessToken);
if (!string.IsNullOrEmpty(access_token))
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
}
var response = await base.SendAsync(request, cancellationToken);
return response;
}
Run Code Online (Sandbox Code Playgroud)
_context.HttpContext当它只是被注入时,什么可能导致为空?
我正在尝试在ASP.NET WebAPI项目中记录整个传入请求和传出响应.虽然我同意DelegatingHandler,但我的雇主坚持使用HttpModule.你怎么向她解释,为什么我们应该使用DelegatingHandler而不是HttpModule?还是我错了?
c# httpmodule asp.net-web-api asp.net-web-api2 delegatinghandler
c# ×6
.net-core ×1
api ×1
asp.net ×1
httpclient ×1
httpcontext ×1
httpmodule ×1
unit-testing ×1