中间件格式响应

问题描述 投票:1回答:1

使用.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);
                }
            }
        }
}
c# .net-core asp.net-core-mvc middleware
1个回答
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);
}

或者我个人的偏好是创建自定义ErrorResult,它实现IActionResult或继承ObjectResult,您可以使用对象而不是字符串格式化消息:

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(...));
...
热门问题
推荐问题
最新问题