I use FastEndpoints over ASP.NET Core minimal API and want to sign the response body which is in application/json
format.
I think instead of calling SendAsync(MyResponse)
I need to:
MyResponse
to JSON,Response.Header
I'd like to use the same JSON serializer with exactly the same options as if I call SendAsync(MyResponse)
. And I don't know how to access the serializer from endpoint.
What I tried to do:
I saw the answer how to replace Body.Stream
at the middleware but I don't think it's a good idea. In addition I need to sign only specific endpoints.
I tried to use IPostProcessor
but I can't read from response Body.
I tried to use IResponseInterceptor
but it seems to just add
I use custom json options like this:
var app = bld.Build();
app
.UseAuthentication()
.UseAuthorization()
.UseFastEndpoints(c =>
{
c.Endpoints.RoutePrefix = "api/v1";
c.Serializer.Options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.SnakeCaseUpper));
})
.UseSwaggerGen()
;
a custom send extension method should get the job done nicely. something like the following:
var bld = WebApplication.CreateBuilder(args);
bld.Services
.Configure<JsonOptions>(o => o.SerializerOptions.PropertyNamingPolicy = null)
.AddFastEndpoints()
.SwaggerDocument();
var app = bld.Build();
app.UseFastEndpoints()
.UseSwaggerGen();
app.Run();
sealed class MyResponse
{
public string Name { get; set; }
}
sealed class MyEndpoint : Ep.NoReq.Res<MyResponse>
{
public override void Configure()
{
Get("test");
AllowAnonymous();
}
public override async Task HandleAsync(CancellationToken c)
{
await this.SendSignedResponse(new MyResponse { Name = "test" });
}
}
static class SendExtensions
{
public static Task SendSignedResponse<TResponse>(this IEndpoint ep, TResponse dto)
{
var jsonOptions = ep.HttpContext.Resolve<IOptions<JsonOptions>>().Value.SerializerOptions;
var json = JsonSerializer.Serialize(dto, jsonOptions);
var md5 = BitConverter.ToString(MD5.HashData(Encoding.UTF8.GetBytes(json))).Replace("-", "").ToLower();
ep.HttpContext.MarkResponseStart();
ep.HttpContext.Response.Headers.Append("x-signature", md5);
return ep.HttpContext.Response.SendStringAsync(json);
}
}