使用.NET Core,C#。
我在启动时添加了中间件,因此我可以设置错误响应的格式<<。但是不幸的是,当它们不是错误响应时,我似乎已经失去了响应。我必须先阅读响应然后再写回吗?
public async Task Invoke(HttpContext context)
{
var body = context.Response.Body;
using (var newBody= new MemoryStream())
{
context.Response.Body = newBody;
await _next(context);
if (context.Response.StatusCode != 200 && context.Response.StatusCode != 206)
{
context.Response.Body = body;
updatedBody.Seek(0, SeekOrigin.Begin);
var msg= new StreamReader(updatedBody).ReadToEnd();
if (msg.Length > 0) {
context.Response.ContentType = _messageParser.GetFormat();
var response = _messageParser.MakeItPretty(msg);
await context.Response.WriteAsync(response);
}
}
}
}
答案 0 :(得分:1)
这是因为您要处置newBody
,所以当响应不是错误响应时,整个响应主体就会被丢弃。您可以创建else
语句并将响应复制到原始body
:
if (context.Response.StatusCode != 200 && context.Response.StatusCode != 206)
{
...
}
else
{
context.Response.Body = body;
newBody.Seek(0, SeekOrigin.Begin);
await newBody.CopyTo(context.response.Body);
}
或者我个人的喜好是创建实现IActionResult或继承ObjectResult的自定义ErrorResult,您可以在其中使用对象而不是字符串来格式化消息:
public class ErrorResult : ObjectResult
{
public ErrorResult(MyError error)
: base(error)
{
StatusCode = 400;
}
public override Task ExecuteResultAsync(ActionContext context)
{
var messageParser = context.HttpContext.RequestServices.GetService(typeof(IMessageParser));
ContentTypes.Add(messageParser.GetFormat());
<other modifications>
return base.ExecuteResultAsync(context);
}
然后将其返回到控制器中
...
return new ErrorResult(new MyError(...));
...