The accepted answer doesn't include the XML declaration, which may or may not matter. Below is a simple extension method for XDocument
that prepends the XML declaration. Otherwise, the technique is identical:
// 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);
If you want, you can also skip the step of converting the XDocument
to a string
(which is UTF-16 encoded), and just go right to UTF-8 bytes:
// 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();
For a third option, XDocument.Save
/XmlWriter
can also output to a string
via StringBuilder
(as shown in the documentation). That is useful if you want a string
but need control over formatting (such as whether to use indentation). Just be aware that the XML declaration generated via this method will always say "utf-16" (regardless of XmlWriterSettings.Encoding
), so you probably want to specify XmlWriterSettings.OmitXmlDeclaration = true
and add the declaration manually afterward. See this question for some discussion of that issue.