首页 > 解决方案 > 在 NET Core Web API 中使用 application/x-www-form-urlencoded 内容类型但 XML 正文处理请求

问题描述

我有一个 .NET Core 2.1 Web API 控制器和方法,它应该通过 HTTP 使用来自外部服务的 POST XML 请求。下面是控制器动作的方法头。

    [HttpPost]
    [Produces("application/xml")]
    public async Task<IActionResult> PostReceivedMessage([FromBody] ReceivedMessage receivedMessage)

我编写了一个自定义 XML 输入格式化程序来处理 XML 请求,当我将来自 Postman 的示例 XML 请求发布到应用程序的控制器操作时,它工作得很好。但是当服务发送类似的请求时,应用程序的响应状态为 400,Bad Request。

经过一番调试,我发现请求进来了

内容类型:application/x-www-form-urlencoded

而不是人们可能期望的 application/xml 或 text/xml 。如果我更改标头以匹配外部服务发送的请求中的内容类型,则应用程序会表现出相同的行为。

我假设 x-www-form-urlencoded 用于表单数据,因为当我将操作标头更改为时模型绑定不起作用:

public async Task<IActionResult> PostReceivedMessage([FromForm] ReceivedMessage receivedMessage)

由于我无法控制外部服务,我应该如何使控制器操作能够处理以 x-www-form-urlencoded 作为内容类型的 XML 请求?

更新:以下是一个示例请求:

POST /check/api/receivedmessages HTTP/1.1
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.7.0_45
Host: xxx.xxx.xxx.xxx
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-type: application/x-www-form-urlencoded
Content-Length: 270

<Request><requestId>95715274355861000</requestId><msisdn>345678955041</msisdn><timeStamp>2019/10/20 02:23:55</timeStamp><keyword>MO</keyword><dataSet><param><id>UserData</id><value>VHVqrA==</value></param><param><id>DA</id><value>555</value></param></dataSet></Request>

标签: c#xmlasp.net-core-webapicontent-typeasp.net-core-2.1

解决方案


获取字符串并将 xml 字符串转换为 C# 对象很简单:

[HttpPost]
[Produces("application/xml")]      
public async Task<IActionResult> PostReceivedMessage([FromForm]string receivedMessage)
    {

        XmlSerializer serializer = new XmlSerializer(typeof(ReceivedMessage));
        ReceivedMessage data;
        using (TextReader reader = new StringReader(receivedMessage))
        {
             data = (ReceivedMessage)serializer.Deserialize(reader);
        }


        return Ok(data);
    }

推荐阅读