【问题标题】:XML Message sent over MSMQ does not include encoding通过 MSMQ 发送的 XML 消息不包括编码
【发布时间】:2018-03-21 13:05:35
【问题描述】:

我正在编写一个使用 MSMQ 的应用程序,但遇到了一个与 XML 声明标记的编码属性有关的问题。

我正在构造如下消息:

string xmlmsg = reqText.Text;
XmlDocument xdoc = new XmlDocument();
xdoc.Load(new StringReader(xmlmsg));

xdoc.InsertBefore(xdoc.CreateXmlDeclaration("1.0", "UTF-8", "yes"), xdoc.DocumentElement);

Message _msg = new Message();

_msg.BodyStream = new MemoryStream(Encoding.ASCII.GetBytes(xdoc.OuterXml));
reqQueue.Send(_msg, "XML Request");

xdoc.OuterXml 的控制台输出显示包含编码:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

但是当我通过 MSMQ 发送消息时,编码属性被删除了。

<?xml version="1.0" standalone="yes"?>

我在这里错过了什么?

【问题讨论】:

  • Message.Formatter 属性很重要。默认是 XmlMessageFormatter,它肯定对 body 应该如何编码有自己的想法。

标签: c# .net msmq windows-server-2008-r2


【解决方案1】:

您错过了 XmlDeclaration 文档中的 note

注意:如果 XmlDocument 保存到 TextWriter 或 XmlTextWriter,则此编码值将被丢弃。而是使用 TextWriter 或 XmlTextWriter 的编码。这确保了可以使用正确的编码读回写出的 XML。

试试这段代码:

string xmlmsg = reqText.Text;
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(xmlmsg);

using (Message _msg = new Message())
using (var memStream = new MemoryStream())
using (var writer = XmlWriter.Create(memStream))
{
     writer.WriteStartDocument(standalone: true);
     xdoc.WriteTo(writer);
     writer.Flush();
     memStream.Seek(0, SeekOrigin.Begin);

     _msg.BodyStream = memStream;
     reqQueue.Send(_msg, "XML Request");
}

【讨论】:

  • 这包括 XML 之前的 BOM,这会导致 MSMQ 出现问题,因为它不是文件。
  • new System.Text.UnicodeEncoding(false, false, true) 用于不带BOM 的UTF-16(小端序)。
  • 对于任何 xml 解析器来说,包含 BOM 都应该不是问题,即使它不是“文件”。并且 MSMQ 并不关心你放了哪些字节。所以你的评论不是你的问题。
【解决方案2】:

原来编码是错误的。这是实际工作的简化代码:

        Message _msg = new Message
        {
            Formatter = new XmlMessageFormatter(),
            BodyStream = new MemoryStream(Encoding.Unicode.GetBytes(_xmlmsg))
        };
        reqQueue.Send(_msg, "XML Request");

它必须是 Unicode,而不是 ASCII。

【讨论】:

  • 只要您使用 DOM 文档,编码就不会出错或正确。将 DOM 模型导出到字符串或缓冲区后,编码就会生效。因此,BOM 标记(如果有)和编码标头将帮助解析器代码做相反的事情:将 XML 内容导入另一端的 DOM 模型。
  • 你是对的。接收方期望它是 Unicode,但从我的测试中我看不到他们收到了什么。只有在摆弄编码之后,我才能正确处理。所以这里 MSMQ 没有错。
  • 文档编码是什么并不重要(只要声明正确——_这是 XML 序列化程序的工作_),Unicode 代码点的序列表示将是相同的。注意:Encoding.Unicode 是 Unicode 字符集的 UTF-16 编码(其历史悠久)。
  • 我认为您的 xml 声明说的是“utf-8”。用 utf-16 编码是不明智的。请改用 Encoding.UTF8。
  • 即使编码需要是 unicode,另一方也期待字符串 &lt;?xml version="1.0" encoding="UTF-8" ?&gt;。我在那里能做的不多,我也不知道为什么会这样。
猜你喜欢
  • 2017-04-27
  • 1970-01-01
  • 2013-03-30
  • 2018-02-02
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 1970-01-01
相关资源
最近更新 更多