I have the following legacy code that modifies WCF message:
private void ModifyReceivedRequest(ref Message message)
{
MemoryStream ms = new MemoryStream();
Encoding encoding = Encoding.UTF8;
XmlWriterSettings writerSettings = new XmlWriterSettings { Encoding = encoding };
writerSettings.ConformanceLevel = ConformanceLevel.Fragment;
writerSettings.Indent = true;
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(XmlWriter.Create(ms, writerSettings));
message.WriteBodyContents(writer);
writer.Flush();
var array = ms.ToArray(); // 56896306 size
string messageBodyString = encoding.GetString(array);
// change the message body
messageBodyString = messageBodyString.Replace("</applicationStructureData>", "</applicationStructureData><srcDataArray>");
messageBodyString = messageBodyString.Replace("</applicationData>", "</srcDataArray></applicationData>");
ms = new MemoryStream(encoding.GetBytes(messageBodyString));
XmlReader bodyReader = XmlReader.Create(ms);
Message originalMessage = message;
message = Message.CreateMessage(originalMessage.Version, null, bodyReader);
message.Headers.CopyHeadersFrom(originalMessage);
}
encoding.GetString(array)
throws an OutOfMemoryException
. Is there any other ways how can be message body be modified without using these conversions?
The way to solve it, is to get rid of conversion to string.
private void ModifyReceivedRequest(ref Message message)
{
MemoryStream ms = new MemoryStream();
Encoding encoding = Encoding.UTF8;
XmlWriterSettings writerSettings = new XmlWriterSettings { Encoding = encoding };
writerSettings.ConformanceLevel = ConformanceLevel.Fragment;
writerSettings.Indent = true;
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(XmlWriter.Create(ms, writerSettings));
message.WriteBodyContents(writer);
writer.Flush();
ms.Position = 0;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(ms);
ms.Flush();
ms = new MemoryStream();
// XML stuff
GC.Collect();
xDoc.Save(ms);
ms.Position = 0;
XmlReader bodyReader = XmlReader.Create(ms);
Message originalMessage = message;
message = Message.CreateMessage(originalMessage.Version, null, bodyReader);
message.Headers.CopyHeadersFrom(originalMessage);
}