У меня есть приложение, которое отображает содержимое сообщений в очереди сообщений MSMQ. Существует проблема с MSMQ в Windows 7, не сохраняющая истинный тип объекта данных в теле сообщения. В этом примере я отправляю byte [], а затем, когда я его получаю, это уже не байтовый массив, а упакованный документ XML-контейнера. В Windows XP у меня никогда не было этой проблемы, и свойство Message.Body всегда было правильно установлено в байт [].
Вот код сжатия:
public void SendWithCompression(string Message)
{
try
{
// Compress the message data in memory.
byte[] UncompressedData = Encoding.UTF8.GetBytes(Message);
byte[] CompressedData = null;
MemoryStream s = new MemoryStream();
using (GZipStream z = new GZipStream(s, CompressionMode.Compress))
{
z.Write(UncompressedData, 0, UncompressedData.Length);
}
CompressedData = s.ToArray();
if (_Transaction != null)
{
_Transaction.Begin();
base.Send(CompressedData, _Transaction);
_Transaction.Commit();
}
else
{
base.Send(CompressedData);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Вот содержимое сообщения для тестового сообщения. Это заканчивается как XML-документ, который упаковывает закодированные двоичные данные .:
<?xml version="1.0"?>..<base64Binary>H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Ih63edMefTsvy2rv8V3+4/8ByygBlxMAAAA=</base64Binary>
Вот код декомпрессии, который он использует:
String Data;
//Get message and format XML
System.Messaging.Message m = MessagesList[ListIndex].Tag;
m.Formatter = new XmlMessageFormatter(new Type[]
{
typeof(string), // Send raw plain strings
typeof(byte[]), // Array of binary data
typeof(XmlNode) // Xml document
});
m.BodyStream.Position = 0;
Data = m.Body.ToString();
if (m.Body.GetType() == typeof(byte[]))
{
try
{
// The message body is an array of binary data.
// Assume it is a GZIP stream of compressed data.
byte[] CompressedData = (byte[])m.Body;
byte[] UncompressedData = null;
// Decompress it.
MemoryStream s = new MemoryStream(CompressedData);
using (GZipStream z = new GZipStream(s, CompressionMode.Decompress))
{
UncompressedData = MyExtensions.ReadRemainingBytes(z);
}
// Turn the bytes back into a string.
Data = Encoding.UTF8.GetString(UncompressedData);
}
catch
{
Data = "Unknown binary data: " +
BitConverter.ToString((byte[])m.Body, 0);
}
}
if (m.Body.GetType() == typeof(XmlElement))
{
XmlElement el = (XmlElement)m.Body;
if (el.Name == "string")
Data = el.InnerText;
else
Data = el.OuterXml;
}
Я хотел бы отметить, что я устанавливаю средство форматирования сообщения, которое является первым шагом к тому, чтобы тело автоматически помещало "box" и "unbox" в очередь.
В Windows XP m.Body.GetType () == byte [], как и ожидалось. Но в Windows 7 m.Body.GetType () == XmlElement, то есть оболочка XML. Он больше не «распаковывает» сообщение.
Нам нужно сделать что-то по-другому? Однажды мы работали над этим для отправки строк, как вы можете видеть в конце функции приема, но я хотел бы найти реальный ответ, почему этот код ведет себя по-разному в Windows 7.