简体   繁体   English

XML 请求主体未在 model 中反序列化 web API

[英]XML request body is not deserialized in model binding for web API

I've read a bit about XML serialization in ASP.NET Core Web API. The default is JSON but XML might also be used sometimes.我在 ASP.NET Core Web API 中阅读了一些关于 XML 序列化的内容。默认值为 JSON,但有时也可能使用 XML。 So I wanted to extend my API to support both.所以我想扩展我的 API 以支持两者。 It was easy to make it output responses in the XML format.以 XML 格式生成 output 响应很容易。 but it won't ever accept XML requests.但它永远不会接受 XML 请求。 I can throw in any request body as JSON but as soon as I change the content-type and body to XML, nothing is read anymore.我可以将任何请求正文作为 JSON 抛出,但是一旦我将内容类型和正文更改为 XML,就不会再读取任何内容。 There is no error.没有错误。 The controller action just receives an empty object, as if the request body was empty. controller 动作只是接收到一个空的 object,就好像请求正文是空的一样。

What's the problem here?这里有什么问题? Has .NET 7 silently dropped support for XML without removing the API for it? .NET 7 是否默默地放弃了对 XML 的支持,而没有为它移除 API? Do I need some secret sauce that isn't shown in any of the Microsoft documentation and other web sources?我是否需要一些未在任何 Microsoft 文档和其他 web 来源中显示的秘方? Can I debug into it somehow?我可以以某种方式调试它吗?

Here are the parts of my code that I consider relevant:以下是我认为相关的代码部分:

Startup.cs:启动.cs:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers()
            // Also tried something within the callback, setting input formats explicitly
            .AddXmlSerializerFormatters();
            // Also tried AddXmlDataContractSerializerFormatters() and both
    }
}

Controller: Controller:

[ApiController]
[Route("sample")]
public class SampleController : ControllerBase
{
    [HttpPost("time")]
    [Consumes("application/json", "application/xml")]
    // Also tried leaving only xml here, removing json completely
    // Also tried text/xml
    [Produces("application/json", "application/xml")]
    public IActionResult PostTime([FromBody] TimeConfig config)
    {
        // Should see something here in config, but it's just defaults
        // (MinTime, false, null)
    }
}

Model: Model:

// Also tried with [Serializable]
// Also tried with some XML attribute I can't remember
public class TimeConfig
{
    public DateTimeOffset CurrentTime { get; set; }
    public bool IsNtpEnabled { get; set; }
    public string? NtpServer { get; set; }
}

Sent request: (see, certainly not false and null!)发送请求:(看到了,肯定不是false和null!)

<TimeConfig>
    <currentTime>2023-01-20T22:41:26.558Z</currentTime>
    <isNtpEnabled>true</isNtpEnabled>
    <ntpServer>string</ntpServer>
</TimeConfig>

(Also tried with <?xml version="1.0" encoding="UTF-8"?> in front) (也尝试在前面使用<?xml version="1.0" encoding="UTF-8"?>

Request headers:请求标头:

Accept: */*
Content-Type: application/xml

The problem was from the parsed XML in which the XML elements are case-sensitive.问题来自已解析的 XML,其中 XML 元素区分大小写。

<TimeConfig>
    <currentTime>2023-01-20T22:41:26.558Z</currentTime>
    <isNtpEnabled>true</isNtpEnabled>
    <ntpServer>string</ntpServer>
</TimeConfig>

Solutions解决方案

  1. Either reformat the XML elements to Pascal case to match with the properties name in TimeConfig class or将 XML 元素重新格式化为 Pascal 大小写以匹配TimeConfig class 中的属性名称或

  2. Apply the XmlElement attribute to the properties below:XmlElement属性应用于以下属性:

public class TimeConfig
{
    [XmlElement("currentTime")]
    public DateTimeOffset CurrentTime { get; set; }
    [XmlElement("isNtpEnabled")]
    public bool IsNtpEnabled { get; set; }
    [XmlElement("ntpServer")]
    public string? NtpServer { get; set; }
}

Demo演示

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM