最小 API 和 XML 格式化程序

And*_*ejT 6 asp.net asp.net-core .net-6.0

在 .NET 6 中尝试最少的 API,但无法使其与 XML 内容类型一起使用。如果我使用标准控制器,则使用.AddXmlSerializerFormatters()扩展可以完成这项工作:

builder.Services.AddControllers().AddXmlSerializerFormatters();
Run Code Online (Sandbox Code Playgroud)

但是当我从控制器切换到 时.MapPost(..),我开始收到 415 HTTP 响应。

app.MapPost("/endpoint", ([FromBody] Request request) => {})
.Accepts<Request>("text/xml");
Run Code Online (Sandbox Code Playgroud)

HTTP 响应:415 Microsoft.AspNetCore.Http.BadHttpRequestException:需要受支持的 JSON 媒体类型,但得到“text/xml”

有没有其他方法可以声明可使用最少 API 的 XML 格式化程序?

Man*_*chs 2

正如guru-stron链接的帖子所建议的,可以通过实现您自己提供BindAsync方法的包装模型来传递 XML 文档。

internal sealed class XDocumentModel
{
    public XDocumentModel(XDocument document) => Document = document;

    public XDocument Document { get; init; }

    public static async ValueTask<XDocumentModel?> BindAsync(HttpContext context, ParameterInfo parameter)
    {
        if (!context.Request.HasXmlContentType())
            throw new BadHttpRequestException(
                message: "Request content type was not a recognized Xml content type.",
                StatusCodes.Status415UnsupportedMediaType);

        return new XDocumentModel(await XDocument.LoadAsync(context.Request.Body, LoadOptions.None, CancellationToken.None));
    }
} 
Run Code Online (Sandbox Code Playgroud)

我向 HttpRequest 添加了一个扩展方法,以方便进行内容类型验证。

internal static class HttpRequestXmlExtensions
{
    public static bool HasXmlContentType(this HttpRequest request)
        => request.Headers.TryGetValue("Content-Type", out var contentType)
        && string.Equals(contentType, "application/xml", StringComparison.InvariantCulture);
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过最小 API 端点直接使用该模型作为参数。

app.MapGet("/xml-test", (XDocumentModel model) =>
{
    // model.Document <- your passed xml Document
    return Results.Ok(new { Value = model.Document.ToString() });
})
Run Code Online (Sandbox Code Playgroud)

最后一些想法: 此实现使您能够将通用 XML 文档传递到端点。但是,如果您期望某种文档结构,则可以通过使 XDocumentModel 期望通用类型参数并从 XDocument 实例中提取该类型的属性来实现此目的。