我有一个正在使用的Owin中间件类。目的是在检测到401、403或405 HTTP状态代码时覆盖响应正文,并用JSON对象替换该正文。到目前为止,这是我的方法:
public override async Task Invoke(IOwinContext context)
{
await Next.Invoke(context);
if (context.Response.StatusCode == 401 || context.Response.StatusCode == 403 || context.Response.StatusCode == 405)
{
var owinResponse = context.Response;
var owinResponseStream = owinResponse.Body;
var responseBuffer = new MemoryStream();
owinResponse.Body = responseBuffer;
string message;
switch (context.Response.StatusCode)
{
case 401:
message = "unauthorized request";
break;
case 403:
message = "forbidden request";
break;
default:
message = "request not allowed";
break;
}
var newResponse = new ResponseMessage<string>
{
IsError = true,
StatusCode = (HttpStatusCode) Enum.Parse(typeof(HttpStatusCode), context.Response.StatusCode.ToString()),
Data = null,
Message = message
};
var customResponseBody = new StringContent(JsonConvert.SerializeObject(newResponse));
var customResponseStream = await customResponseBody.ReadAsStreamAsync();
await customResponseStream.CopyToAsync(owinResponseStream);
owinResponse.ContentType = "application/json";
owinResponse.ContentLength = customResponseStream.Length;
owinResponse.StatusCode = 200;
owinResponse.Body = owinResponseStream;
}
}
在大多数情况下,它可以正常工作,但是响应正文被附加到而不是被替换。例如,在401错误的情况下,响应主体为:
{"message":"Authorization has been denied for this request."}
{"IsError":true,"StatusCode":401,"Data":null,"Message":"unauthorized request"}
代替:
{"IsError":true,"StatusCode":401,"Data":null,"Message":"unauthorized request"}
我确定这与我写给响应正文的方式有关,但是到目前为止,没有任何东西可以解决问题。
任何建议将不胜感激。
谢谢
答案 0 :(得分:2)
因为您在await Next.Invoke(context);
之后写了以下代码
await Next.Invoke(context);
if (context.Response.StatusCode == 401 || context.Response.StatusCode == 403 || context.Response.StatusCode == 405)
{
var owinResponse = context.Response;
var owinResponseStream = owinResponse.Body;
var responseBuffer = new MemoryStream();
owinResponse.Body = responseBuffer;
错了。
下一个代码片段可以根据需要工作:
public override async Task Invoke(IOwinContext context)
{
var owinResponse = context.Response;
var owinResponseStream = owinResponse.Body;
var responseBuffer = new MemoryStream();
owinResponse.Body = responseBuffer;
await Next.Invoke(context);
if (context.Response.StatusCode == 401 || context.Response.StatusCode == 403 || context.Response.StatusCode == 405)
{
string message;
switch (context.Response.StatusCode)
{
case 401:
message = "unauthorized request";
break;
case 403:
message = "forbidden request";
break;
default:
message = "request not allowed";
break;
}
var newResponse = new ResponseMessage<string>
{
IsError = true,
StatusCode = (HttpStatusCode) Enum.Parse(typeof(HttpStatusCode), context.Response.StatusCode.ToString()),
Data = null,
Message = message
};
var customResponseBody = new StringContent(JsonConvert.SerializeObject(newResponse));
var customResponseStream = await customResponseBody.ReadAsStreamAsync();
await customResponseStream.CopyToAsync(owinResponseStream);
owinResponse.ContentType = "application/json";
owinResponse.ContentLength = customResponseStream.Length;
owinResponse.StatusCode = 200;
owinResponse.Body = owinResponseStream;
}
}
答案 1 :(得分:0)
当您第一次将响应主体设置为内存流时,光标(当前位置)将移动到它的末尾。 owinResponse.Body = responseBuffer;
,因此,我们存储了{"message":"Authorization has been denied for this request."}
,光标指向末尾。
同样,在方法末尾,您编写了新的响应owinResponse.Body = owinResponseStream;
,其中包含消息{"IsError":true,"StatusCode":401,"Data":null,"Message":"unauthorized request"}
由于当前位置指向流的末尾,因此它将追加。
尝试删除第一组正文 ,因为您不需要原始回复消息。owinResponse.Body = responseBuffer;