将XmlDocument发布到网络服务器的正确方法是什么?这是骨架功能:
public static void PostXml(XmlDocument doc, String url)
{
//TODO: write this
}
现在我使用:
//Warning: Do not use this PostXml implmentation
//It doesn't adjust the Xml to match the encoding used by WebClient
public static void PostXml(XmlDocument doc, String url)
{
using (WebClient wc = new WebClient())
{
wc.UploadString(url, DocumentToStr(doc));
}
}
DocumentToStr
是一种完全有效且正确的方法:
/// <summary>
/// Convert an XmlDocument to a String
/// </summary>
/// <param name="doc">The XmlDocument to be converted to a string</param>
/// <returns>The String version of the XmlDocument</returns>
private static String DocumentToStr(XmlDocument doc)
{
using (StringWriter writer = new StringWriter())
{
doc.Save(writer);
return writer.ToString();
}
}
我实现PostXml
的问题在于它按原样发布String 。这意味着(在我的情况下)http请求是:
POST https://stackoverflow.com/upload.php HTTP/1.1
Host: stackoverflow.com
Content-Length: 557
Expect: 100-continue
<?xml version="1.0" encoding="utf-16"?>
<AccuSpeedData MACAddress="00252f21279e" Date="2010-10-07 10:49:41:768">
<Secret SharedKey="1234567890abcdefghijklmnopqr" />
<RegisterSet TimeStamp="2010-10-07 10:49:41:768">
<Register Address="total:power" Type="Analog" Value="485" />
<Register Address="total:voltage" Type="Analog" Value="121.4" />
<Register Address="total:kVA" Type="Analog" Value="570" />
</RegisterSet>
</AccuSpeedData>
您会注意到xml声明的编码不正确:
<?xml version="1.0" encoding="utf-16"?>
WebClient
未在utf-16
unicode中发送请求,这就是.NET中的字符串存储方式。我甚至知道 WebClient
使用的编码。
xml的http帖子需要正确编码,这通常发生在调用:
期间Save(textWriter)
在致电Save
期间,XmlDocument
对象将根据要求保存到的Encoding
的TextWriter
调整xml声明。不幸的是,WebClient
没有公开我可以将XmlDocument保存到的TextWriter
。
答案 0 :(得分:0)
这是solution。子类StringWriter:
public class StringWriterWithEncoding : StringWriter
{
Encoding encoding;
public StringWriterWithEncoding (StringBuilder builder, Encoding encoding) :base(builder)
{
this.encoding = encoding;
}
public override Encoding Encoding
{
get { return encoding; }
}
}
答案 1 :(得分:0)
为什么不使用已指定编码的XmlWriter
。 XmlWriter
需要基础流,但您只需给它一个MemoryStream
。
至于使用哪种编码,为什么不通过WebClient.Encoding
? :
public static void PostXml(XmlDocument doc, String url)
{
using (WebClient wc = new WebClient())
{
wc.UploadData(url, DocumentToData(doc, wc.Encoding));
}
}
private static byte[] DocumentToData(XmlDocument doc, Encoding encoding)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = encoding;
settings.Indent = true;
using (MemoryStream s = new System.IO.MemoryStream())
{
using (XmlWriter writer = XmlWriter.Create(s, settings))
{
doc.Save(writer);
// You could make the return type string, but why make
// the web client round trip it back to bytes again?
// return encoding.GetString(s.GetBuffer());
return s.GetBuffer();
}
}
}
我还没有在真实的应用程序中对此进行过测试,所以如果我在这里遗漏了一些东西,请告诉我。