Search code examples
c#wcfout-of-memorymessage

Modifying WCF message body


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?


Solution

  • 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);
        }