Skip to content

Instantly share code, notes, and snippets.

@dj-nitehawk
Created September 1, 2023 10:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dj-nitehawk/c66990afc31ed9ad5063402fa295116a to your computer and use it in GitHub Desktop.
Save dj-nitehawk/c66990afc31ed9ad5063402fa295116a to your computer and use it in GitHub Desktop.
Serialization of XML with FastEndpoints
var bld = WebApplication.CreateBuilder();
bld.Services
.AddSingleton(typeof(IRequestBinder<>), typeof(CustomBinder<>))
.AddFastEndpoints()
.SwaggerDocument();
var app = bld.Build();
app.UseAuthorization()
.UseFastEndpoints()
.UseSwaggerGen();
app.Run();
public class CustomBinder<TRequest> : RequestBinder<TRequest> where TRequest : notnull
{
public override async ValueTask<TRequest> BindAsync(BinderContext ctx, CancellationToken cancellation)
{
if (ctx.HttpContext.Request.ContentType == "application/xml")
{
var serializer = new XmlSerializer(typeof(TRequest));
using var reader = new StreamReader(ctx.HttpContext.Request.Body);
string requestBody = await reader.ReadToEndAsync();
using var stringReader = new StringReader(requestBody);
return (TRequest)serializer.Deserialize(stringReader);
}
return await base.BindAsync(ctx, cancellation);
}
}
public static class EndpointExtensions
{
public static async Task SendXMLAsync<TResponse>(this IEndpoint ep,
TResponse response,
int statusCode = 200,
string contentType = "application/xml",
CancellationToken cancellationToken = default)
{
ep.HttpContext.MarkResponseStart();
ep.HttpContext.Response.StatusCode = statusCode;
ep.HttpContext.Response.ContentType = contentType;
var xmlSerializer = new XmlSerializer(typeof(TResponse));
using var stream = new MemoryStream();
xmlSerializer.Serialize(stream, response);
stream.Position = 0;
await stream.CopyToAsync(ep.HttpContext.Response.Body, cancellationToken);
}
}
public class Request
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Response
{
public string FullName { get; set; }
}
public class Endpoint : Endpoint<Request, Response>
{
public override void Configure()
{
Post("test-xml");
AllowAnonymous();
Description(x => x
.Accepts<Request>("application/xml")
.Produces<Response>(200, "application/xml"),
clearDefaults: true);
}
public override async Task HandleAsync(Request r, CancellationToken c)
{
var response = new Response
{
FullName = r.FirstName + " " + r.LastName
};
await this.SendXMLAsync(response);
}
}
@PGyorgy
Copy link

PGyorgy commented Sep 1, 2023

Thx, this helped a lot with XML responses/requests!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment