【问题标题】:Middleware format response中间件格式响应
【发布时间】:2019-04-03 16:29:20
【问题描述】:

使用 .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);
                }
            }
        }
}

【问题讨论】:

  • 当 StatusCode 不是 200 也不是 206 时,您缺少 ELSE。
  • @jdweng 这应该是一个答案

标签: c# .net-core asp.net-core-mvc middleware


【解决方案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(...));
...

【讨论】:

  • 谢谢!我是否正确地认为我的方法可能非常昂贵?通过使用“等待 newBody.CopyTo(context.response.Body);”我正在复制原始响应,所以如果它是大量数据,我会在内存中复制它吗?
  • 我喜欢自定义的 ErrorResult 方法。谢谢
  • 我决定使用自定义 ErrorResult 方法,因为它更轻量级。
猜你喜欢
  • 2016-07-10
  • 2012-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-02
  • 2014-06-14
  • 1970-01-01
相关资源
最近更新 更多