在调用的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);
}
为了实现你需要什么,你可以创建自己的自定义扩展方法,其中明确指定要使用的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);
}
}