如何使用HttpClient.PostAsync发送XML内容

本文关键字:XML 内容 发送 PostAsync 何使用 HttpClient | 更新日期: 2023-09-27 18:18:28

我正在尝试实现这个rest api:

public async Task<bool> AddTimetracking(Issue issue, int spentTime)
{
    // POST /rest/issue/{issue}/timetracking/workitem
    var workItem = new WorkItem(spentTime, DateTime.Now);
    var httpContent = new StringContent(workItem.XDocument.ToString());
    var requestUri = string.Format("{0}{1}issue/{2}/timetracking/workitem", url, YoutrackRestUrl, issue.Id);
    var respone = await httpClient.PostAsync(requestUri, httpContent);
    if (!respone.IsSuccessStatusCode)
    {
        throw new InvalidUriException(string.Format("Invalid uri: {0}", requestUri));
    }
    return respone.IsSuccessStatusCode;
}

workItem.XDocument包含以下元素:

<workItem>
  <date>1408566000</date>
  <duration>40</duration>
  <desciption>test</desciption>
</workItem>

我从API得到一个错误:Unsupported Media Type

我真的不知道如何解决这个问题,非常感谢帮助。我如何马歇尔一个XML文件通过HTTP POST URI,使用HttpClient ?

如何使用HttpClient.PostAsync发送XML内容

您可能希望在StringContent中设置mediaType,如下所示:

var httpContent = new StringContent(workItem.XDocument.ToString(), Encoding.UTF8, "text/xml");

var httpContent = new StringContent(workItem.XDocument.ToString(), Encoding.UTF8, "application/xml");

你可以使用

var respone = await httpClient.PostAsXmlAsync(requestUri, workItem);
https://msdn.microsoft.com/en-us/library/system.net.http.httpclientextensions_methods

要使用Matt Frear的解决方案,您可能需要添加NuGet Package: Microsoft.AspNet.WebApi.Client

这带来了扩展方法,因此您可以使用:

var respone = await httpClient.PostAsXmlAsync<WorkItem>(requestUri, workItem);

这适用于较新的。net 5,所以假设也适用于asp.net core 3.1

接受的答案不包括XML声明,这可能重要,也可能无关紧要。下面是XDocument的一个简单扩展方法,它在XML声明之前。否则,技术是相同的:

// Extension method
public static string ToStringWithDeclaration(this XDocument doc, string declaration = null)
{
    declaration ??= "<?xml version='"1.0'" encoding='"utf-8'"?>'r'n";
    return declaration + doc.ToString();
}
// Usage (XDocument -> string -> UTF-8 bytes)
var content = new StringContent(doc.ToStringWithDeclaration(), Encoding.UTF8, "text/xml");
var response = await httpClient.PostAsync("/someurl", content);

如果您愿意,也可以跳过将XDocument转换为string(这是UTF-16编码的)的步骤,直接转换为UTF-8字节:

// Extension method
public static ByteArrayContent ToByteArrayContent(
    this XDocument doc, XmlWriterSettings xmlWriterSettings = null)
{
    xmlWriterSettings ??= new XmlWriterSettings();
    using (var stream = new MemoryStream())
    {
        using (var writer = XmlWriter.Create(stream, xmlWriterSettings))
        {
            doc.Save(writer);
        }
        var content = new ByteArrayContent(stream.GetBuffer(), 0, (int)stream.Length);
        content.Headers.ContentType = new MediaTypeHeaderValue("text/xml");
        return content;
    }
}
// Usage (XDocument -> UTF-8 bytes)
var content = doc.ToByteArrayContent();
var response = await httpClient.PostAsync("/someurl", content);
// To view the serialized XML as a string (for debugging), you'd have to do something like:
using var reader = new StreamReader(content.ReadAsStream());
string xmlStr = reader.ReadToEnd();

对于第三个选项,XDocument.Save/XmlWriter也可以通过StringBuilder输出到string(如文档中所示)。如果您想要string,但需要控制格式(例如是否使用缩进),这是有用的。请注意,通过此方法生成的XML声明将始终显示"utf-16"(不管XmlWriterSettings.Encoding),所以您可能希望指定XmlWriterSettings.OmitXmlDeclaration = true,然后手动添加声明。