views:

407

answers:

2

I'm doing some pre-processing of an XML document in a .NET Webservice (Standard .NET SOAP Service) for eventual use in a Silverlight front end.

I'm processing that XML document into a POCO object for ease of use. The object is defined as follows:

public class CACDocument : ITextDocument
{
    #region Properties
    public string Title { get; set; }
    public string Text { get; set; }
    public List<Code> CodeList { get; set; }
    public XElement FormatedText { get; set; }
    #endregion

    #region Constructor
    public CACDocument()
    {
     CodeList = new List<Code>();
    }
    #endregion
}

The Text property in that object contains basically formatted text (line breaks, white space, etc...). The XML node that feeds that property looks like this:

<text>
   A TITLE FOLLOWED BY two line breaks


   Some text followed by a line break

   Some more text that might extend for a paragraph or two followed by more line breaks

   Still more text
</text>

All is fine and format is maintained as I would expect up unitl the Web Services serializes the data to be sent out to the front end. I'm guessing that in an attempt to optimize bandwidth, the serialized object strips the extra whitespace and line breaks from the Text property before sending it out. In this one particular instance, that formatting is important. Is there a way to force the webservice to maintain this whitespace/line break formatting?

I imagine that I code substitute some coding for the items in question, and then convert back on the front end, but that strikes me as a bit of a cludge.

Thanks in advance

+1  A: 

I presume you're referring to ASMX web services?

Actually, I don't think there's a way to do this without serializing as a byte array. Alternatively, you could implement IXmlSerializable and do all the work yourself.


You'll want something like this:

public class CACDocument : ITextDocument {
    // ...
    [XmlIgnore]
    public string Text {get;set;}

    [XmlText]
    public byte[] TextSubstitute {
        get {return System.Text.Encoding.UTF8.GetBytes(Text);}
        set {Text = System.Text.Encoding.UTF8.GetString(value);}
    }
}

That's not tested, but you'll get the idea. You can also use [XmlElement] instead of [XmlText], and specify a different element name.

John Saunders
You are correct in your assumption. So, are you saying that I need to convert the string property to a byte array property, or is there a specific setting that will allow me to explicitly serialize a string as a byte array?
Steve Brouillard
Steve, I'm curious - did you try Thomas' CDATA solution below? I haven't ahd a chance to try it.
John Saunders
Igot caught up in meetings yesterday. I'm going to try his solution today and will comment on it later.
Steve Brouillard
John. I tried Thomas' CDATA solution below and it works like a charm. I don't know about thread safety, but for my purposes, it isn't relevant. In any case where this process would be used, it would be a single call to the web service and the results would be processed into local POCO objects and since it's Silverlight and async anyway, I need to fire an event when proc is complete, so there's no chance the object would be accessed from another thread until that time. It also has the added advantage of limiting data sent accross the wire.
Steve Brouillard
+3  A: 

You can serialize it as a CDATA section :

    [XmlIgnore]
    public string Text { get; set; }

    private static readonly XmlDocument _xmlDoc = new XmlDocument();

    [XmlElement("Text")]
    public XmlCDataSection TextCData
    {
        get
        {
            return _xmlDoc.CreateCDataSection(Text);
        }
        set
        {
            Text = value.Data;
        }
    }

The text will be serialized like that :

<text><![CDATA[A TITLE FOLLOWED BY two line breaks


   Some text followed by a line break

   Some more text that might extend for a paragraph or two followed by more line breaks

   Still more text]]></text>
Thomas Levesque
What's the effect of all those CData sections attached to the document? And, is that thread-safe?
John Saunders
To be honest, I have no idea... maybe the XmlDocument should be a local variable instead, I just wanted to avoid creating many instances of XmlDocument.
Thomas Levesque