Web API 无法使用 utf-16 编码的 XML 绑定 POST 模型

Posted

技术标签:

【中文标题】Web API 无法使用 utf-16 编码的 XML 绑定 POST 模型【英文标题】:Web API not able to bind model for POST with utf-16 encoded XML 【发布时间】:2017-02-16 14:31:40 【问题描述】:

我有一个带有POST 方法的简单Web API 控制器,它接受一个对象。当客户端将数据发布为JSON 时,API 工作正常。即使数据以XMLencoding="utf-8" 发送,模型也会无缝绑定(我在WebApiConfig 中添加了以下行以使用Xml Serialization 而不是DataContract

config.Formatters.XmlFormatter.UseXmlSerializer = true;

下面是我的 ApiController:

public class InfoController : ApiController

    public HttpResponseMessage Post(InfoRequest infoRequest)
    
        //do work and return something
        return Request.CreateResponse(HttpStatusCode.Accepted, infoRequest != null);
    

种类

public class InfoRequest

    public string Id  get; set; 
    public int Total  get; set; 
    public Status Status  get; set; 


public enum Status

    None = 0,
    Confirmed,
    Cancelled

现在当客户端根据一组数据发出请求时,它工作正常

Content-Type: application/json
body:

    "Id": "ACARG021",
    "Total": 20,
    "Status": "Confirmed"

这也很好用

Content-Type: application/xml
body:
<?xml version="1.0" encoding="utf-8"?>
<InfoRequest>
    <Id>ACARG021</Id>
    <Total>20</Total>
    <Status>Confirmed</Status>
</InfoRequest>

但是,当使用 UTF-16 发布 XML 时,模型绑定失败并且控制器方法将 null 传递给它。

Content-Type: application/xml; charset=utf-16
//Accept-Charset: utf-16 //Edit: wrong header, removed
body:
<?xml version="1.0" encoding="utf-16"?>
<InfoRequest>
    <Id>ACARG021</Id>
    <Total>20</Total>
    <Status>Confirmed</Status>
</InfoRequest>

正如其他一些 SO 帖子中所建议的,将此添加到 WebApiConfig 没有帮助

Encoding utf16 = Encoding.GetEncoding("utf-16");
config.Formatters.XmlFormatter.SupportedEncodings.Add(utf16);

【问题讨论】:

您是否也尝试过重置默认的 json 编码?见blogs.msdn.microsoft.com/henrikn/2012/04/22/… 在 dotnet 核心模型绑定中遇到同样的问题。 utf-8 以外的任何编码都不起作用。我也修改了 xmlformatter。没有运气。如果你找到了这个问题的答案,请告诉我,即使这个问题现在已经很古老了。 【参考方案1】:

在服务器端,这应该是开箱即用的。所以我想问题将是你的 POST。内容类型标头应具有正确的编码。将 XML 本身的标头更改为 encoding="utf-16" 是不够的。 试试:

Content-Type: application/xml; charset=utf-16

您还需要以该编码实际发送数据,而不仅仅是更改标头。

【讨论】:

感谢您的回答。但是,在标题中提及字符集并没有多大帮助。 Web API 仍然无法解码。 您能展示一下您是如何进行 POST 的吗?您确定不能将其更改为 UTF-8 吗? UTF-16 将需要通过 TCP/IP 传输双倍数据量。 截至目前(用于测试),我正在使用 Postman 客户端发布与我在问题中提到的完全相同的数据/标题。我拥有这里的服务,而不是客户。 UTF-16 是客户的一些特定要求,因此无法更改。我知道它会增加数据大小,但现在需要让它发挥作用。 您确定使用二进制模式从 Postman 发送 UTF-16 数据吗?在 Postman 中设置 Content-Type 标头是不够的。如果标头显示 UTF-16,但数据是 UTF-8 编码的,则会导致 infoRequest 为空。您可以尝试将Post(InfoRequest infoRequest) 替换为Post(HttpRequestMessage request),然后查看request.Content.ReadAsByteArrayAsync().Result

以上是关于Web API 无法使用 utf-16 编码的 XML 绑定 POST 模型的主要内容,如果未能解决你的问题,请参考以下文章

使用 XDocument 加载编码为 UTF 16 的 xml

(紧急)mysql字段类型转换成utf16

如何使用 C# 将 powershell 脚本编码为 base64 UTF16-LE 字符串

无法读取 UTF-16 文件

将 UTF-16 图像加载到内存中

Windows API:ANSI 和宽字符字符串——是 UTF8 还是 ASCII? UTF-16 还是 UCS-2 LE?