我的OWIN中间件是这样的.(Framework是ASP.NET Web API).
public class MyMiddleware : OwinMiddleware
{
public MyMiddleware(OwinMiddleware next) : base(next) { }
public override async Task Invoke(OwinRequest request, OwinResponse response)
{
var header = request.GetHeader("X-Whatever-Header");
await Next.Invoke(request, response);
response.SetHeader("X-MyResponse-Header", "Some Value");
response.StatusCode = 403;
}
}
Run Code Online (Sandbox Code Playgroud)
问题:
是推荐的做法来源于OwinMiddleware
?我看到在Katana源代码中,一些中间件类来自OwinMiddleware
,有些则不是.
我可以看到请求标头没问题.Next.Invoke
在我的中间件之后设置响应头或状态代码对返回给客户端的响应没有影响.但是,如果我在Next.Invoke
调用之前设置响应标头或状态,则带有标头的响应和我设置的状态将返回给客户端.设置这些的正确方法是什么?
我有一个Web API消息处理程序MyHandler
,我想在OWIN管道中作为中间件运行.所以像这样配置处理程序.
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseHttpMessageHandler(new MyHandler());
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
"DefaultWebApi",
"{controller}/{id}",
new { id = RouteParameter.Optional });
app.UseWebApi(config);
}
}
Run Code Online (Sandbox Code Playgroud)
处理程序非常简单,什么都不做.
public class MyHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{ // <--- breakpoint here
var response = await base.SendAsync(request, cancellationToken);
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
我在里面放了一个断点SendAsync
,它确实打破但是下面的base.SendAsync
炸弹默默地看着我A first chance exception of type 'System.InvalidOperationException' occurred in System.Net.Http.dll
.
我可以很容易地添加 …
这个问题与我在这里提供的答案有关.OP的评论让我思考了一下.我建议在身份验证过滤器IHttpActionResult
的ChallengeAsync
方法中使用类似这样的类.
public Task ChallengeAsync(HttpAuthenticationChallengeContext context,
CancellationToken cancellationToken)
{
context.Result = new ResultWithChallenge(context.Result);
return Task.FromResult(0);
}
public class ResultWithChallenge : IHttpActionResult
{
private readonly IHttpActionResult next;
public ResultWithChallenge(IHttpActionResult next)
{
this.next = next;
}
public async Task<HttpResponseMessage> ExecuteAsync(
CancellationToken cancellationToken)
{
var response = await next.ExecuteAsync(cancellationToken);
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
response.Headers.WwwAuthenticate.Add(
new AuthenticationHeaderValue("Basic", "realm=localhost"));
}
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
而不是这个,我可以简化ChallengeAsync
这个.
public Task ChallengeAsync(HttpAuthenticationChallengeContext context,
CancellationToken cancellationToken)
{
var result = await context.Result.ExecuteAsync(cancellationToken); …
Run Code Online (Sandbox Code Playgroud)