首页 > 解决方案 > 为响应处理添加属性

问题描述

使用 C#、Net Core 3.1

我想知道是否有人可以提供帮助。我想添加“中间件”,但我认为我的要求需要一个属性,因为我只想对特定的 API 操作有选择地执行此操作。在将响应发送到请求客户端之前,如何对响应进行一些处理(例如签署消息并将其添加到响应标头)?

例如

    [HttpGet]
    [PostResponseProcessAttribute]
    public IActionResult GetFoo(int id) {
        return MyFoo();
    }

所以对于这个 GetFoo Action,我想做这样的事情:

public class PostResponseProcessAttribute : Attribute {
    public OnBeforeSendingResponse(){
      var response = Response.Content.ReadAsStringAsync;
     //do some stuff
      response.Headers.Add(results from stuff)
    }
}

它是我需要实现的属性吗?我需要覆盖的功能是什么?此外,一个关键位是响应的格式和状态将被发送到客户端(即通过其他格式化中间件处理等) - 这对于签名很重要,因为任何差异都意味着客户端正在验证响应不同的版本,因此总是失败。

谢谢

标签: c#asp.net-coremiddleware

解决方案


最后,我写了这个:

public sealed class AddHeadersRequiredAttribute : Attribute
{
}

public class AddHeadersMiddleware
{
    private readonly RequestDelegate _next;

    public AddHeadersMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        await using var memory = new MemoryStream();
        var originalStream = context.Response.Body;
        context.Response.Body = memory;

        await _next(context);

        memory.Seek(0, SeekOrigin.Begin);
        var content = await new StreamReader(memory).ReadToEndAsync();
        memory.Seek(0, SeekOrigin.Begin);

        // Now you can manipulate with content
        var attribute = GetAddHeadersRequiredAttributeFromMatchedAction(context);
        if (attribute != null)
            context.Response.Headers.Add("X-Header-1", content);

        await memory.CopyToAsync(originalStream);
        context.Response.Body = originalStream;
    }

    private Attribute GetAddHeadersRequiredAttributeFromMatchedAction(HttpContext context)
    {
        var endpoint = context.GetEndpoint();
        var controllerActionDescriptor = endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>();
        return controllerActionDescriptor?.MethodInfo.GetCustomAttribute<AddHeadersRequiredAttribute>();
    }
}

您可以使用 标记控制器方法AddHeadersRequiredAttributeStartup.Configure然后像这样在你的方法中使用中间件

app.UseMiddleware<AddHeadersMiddleware>();

推荐阅读