HttpClient的不正确序列化不正确、序列化、HttpClient

2023-09-03 17:36:42 作者:我的命运我主宰

在调用的HttpClient的扩展方法 PostAsXmlAsync ,它忽略了 XmlRootAttribute 的类。这种行为是一个错误?

测试

  [Serializable接口]
[XmlRoot(记录)
类账户
{
    [的XmlElement(帐户ID)]
    公众诠释ID {获得;组 }
}


VAR的客户=新的HttpClient();
等待client.PostAsXmlAsync(URL,新的账户())
 

解决方案

综观的 PostAsXmlAsync来源$ C ​​$ C ,我们可以看到它使用 XmlMediaTypeFormatter 它内部使用的DataContractSerializer 和不可以 的XmlSerializer 。前者不尊重 XmlRootAttribute

 公共静态任务< Htt的presponseMessage> PostAsXmlAsync< T>(这HttpClient的客户端,乌里requestUri,T值的CancellationToken的CancellationToken)
{
      返回client.PostAsync(requestUri,价值,新XmlMediaTypeFormatter()
                    的CancellationToken);
}
 
curl可以访问但httpclient不能访问 java访问修饰符可以越权吗

为了实现你需要什么,你可以创建自己的自定义扩展方法,其中明确指定要使用的XmlSerializer

 公共静态类HttpExtensions
{
    公共静态任务< Htt的presponseMessage> PostAsXmlWithSerializerAsync< T>(这HttpClient的客户端,乌里requestUri,T值的CancellationToken的CancellationToken)
    {
        返回client.PostAsync(requestUri,价值,
                      新XmlMediaTypeFormatter {UseXmlSerializer = TRUE},
                      的CancellationToken);
    }
}
 

When calling HttpClient's extension method PostAsXmlAsync, it ignores the XmlRootAttribute on the class. Is this behaviour a bug?

Test

[Serializable]
[XmlRoot("record")]
class Account 
{
    [XmlElement("account-id")]
    public int ID { get; set }
}


var client = new HttpClient();
await client.PostAsXmlAsync(url, new Account())

解决方案

Looking at the source code of PostAsXmlAsync, we can see that it uses XmlMediaTypeFormatter which internally uses DataContractSerializer and not XmlSerializer. The former doesn't respect the XmlRootAttribute:

public static Task<HttpResponseMessage> PostAsXmlAsync<T>(this HttpClient client, Uri requestUri, T value, CancellationToken cancellationToken)
{
      return client.PostAsync(requestUri, value, new XmlMediaTypeFormatter(),
                    cancellationToken);
}

In order to achieve what you need, you can create a your own custom extension method which explicitly specifies to use XmlSerializer:

public static class HttpExtensions
{
    public static Task<HttpResponseMessage> PostAsXmlWithSerializerAsync<T>(this HttpClient client, Uri requestUri, T value, CancellationToken cancellationToken)
    {
        return client.PostAsync(requestUri, value,
                      new XmlMediaTypeFormatter { UseXmlSerializer = true },
                      cancellationToken);
    }
}