Using C#, Net Core 3.1
I am wondering if someone can kindly help. I would like to add "middleware" but I think an Attribute is needed for my requirements as I want to do this selectively on specific API Actions only. How can I do some process (such as Signing a message and add it the response header) on a Response just before it is sent to the requesting client?
For example
[HttpGet]
[PostResponseProcessAttribute]
public IActionResult GetFoo(int id) {
return MyFoo();
}
So for this GetFoo Action, I would like to do something like this:
public class PostResponseProcessAttribute : Attribute {
public OnBeforeSendingResponse(){
var response = Response.Content.ReadAsStringAsync;
//do some stuff
response.Headers.Add(results from stuff)
}
}
Is it an Attribute that I need to implement and what is the function that I need override please? Also, a key bit is that Response is in the format and state that would be sent to to the client (i.e. passed other formatting middleware processing etc.) - this is important for Signing because any discrepancies would mean the client is verifying a response of a different version and therefore always fail.
Thanks
Finally, I wrote this:
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>();
}
}
You can mark controller method with AddHeadersRequiredAttribute
. Then use middleware at your Startup.Configure
method like this
app.UseMiddleware<AddHeadersMiddleware>();