Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Object serialization - convert to xml problem

Status
Not open for further replies.

emblewembl

Programmer
May 16, 2002
171
GB
I am developing a web service which will output a string which the user of the web service can then convert to xml and do whatever they like with it! I am serializing my object then returning the string and it's all working fine. However, I have built a test website to access the webservice and when I try to converty the text to xml I get an error msg saying the first character is invalid.

Here is the serialization code in the webservice:

Code:
 [WebMethod]
    public string GetRP(string TrackId, string RaceDate, string RaceNumber, bool Surface, bool Track, bool Life)
    {
        Serialization ser = new Serialization();
        string outString = ser.Serialize(prediction);
        
    }

    public string Serialize(object objName)
    {
        try
        {
            string XmlizedString = null;
            MemoryStream memoryStream = new MemoryStream();
            XmlSerializer xs = new XmlSerializer(typeof(Prediction));
            XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
            xs.Serialize(xmlTextWriter, objName);

            memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
            XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
            
            XmlizedString = XmlizedString.Trim();
            return XmlizedString;
        }
        catch (Exception e)
        {
            return null;
        }
    }

    private string UTF8ByteArrayToString(byte[] characters)
    {
        UTF8Encoding encoding = new UTF8Encoding();
        string constructedString = encoding.GetString(characters);
        return (constructedString);
    }

And in the test website I am doing this to get the string out of the webservice and convert to xml:

Code:
     PredictorWS.Service pws = new PredictorWS.Service();
     string prediction = pws.GetRacePrediction("B", "14/06/2006", "1", true, true, true);
                
     XmlDocument xDoc = new XmlDocument();
     xDoc.LoadXml(prediction);

The error msg I get is:

Code:
Data at the root level is invalid. Line 1, position 1.

Just before this line:
<?xml version=\"1.0\" encoding=\"utf-8\"?>

there is a weird character, like a small square. Where is this coming from and what am I doing wrong? Is the problem at the web service side of things or in the test web site? Hope you can help!

i love chocolate
 
try Econding.ASCII int his line:

XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

 
I think the XmlDocument class uses unicode by default. I don't know if there's some sort of property for XmlDocument to switch encoding type.

Try changing Encoding.UTF8 (XmlTextWriter) to unicode first and see if this is true (i don't have .net on the machine i'm posting). If it is, then i suggest putting one or few more lines of codes making sure both provider and consumer agrees on the encoding type.
 
yeah, default xml is UTF8 - which is simple unicode. If you have things like non-simple chinese characters to deal with then they won't work. :)
 
Silly me! Thanks for clearing that out. (Need... more... caffeine... !!! :p)

Will it help if you just turn off the BOM?
Code:
... = [COLOR=blue]new[/color] XmlTextWriter(memoryStream, new UTF8Encoding([b]false[/b]));
 
Thanks for all the help! I ended up finding another example of the same thing, tried it, and hey presto it now works perfectly. Here's the code in case anyone else needs it:

Code:
public string Serialize(object objName)
    {
        MemoryStream stream = null;
        TextWriter writer = null;
        try
        {
            stream = new MemoryStream(); // read xml in memory
            writer = new StreamWriter(stream, Encoding.Unicode);
            // get serialise object
            XmlSerializer serializer = new XmlSerializer(typeof(Prediction));
            serializer.Serialize(writer, objName); // read object
            int count = (int)stream.Length; // saves object in memory stream
            byte[] arr = new byte[count];
            stream.Seek(0, SeekOrigin.Begin);
            // copy stream contents in byte array
            stream.Read(arr, 0, count);
            UnicodeEncoding utf = new UnicodeEncoding(); // convert byte array to string
            return utf.GetString(arr).Trim();
        }
        catch
        {
            return string.Empty;
        }
        finally
        {
            if (stream != null) stream.Close();
            if (writer != null) writer.Close();
        }
    }



    /// <summary>
    /// To convert a Byte Array of Unicode values (UTF-8 encoded) to a complete String.
    /// </summary>
    /// <param name="characters">Unicode Byte Array to be converted to String</param>
    /// <returns>String converted from Unicode Byte Array</returns>
    private string UTF8ByteArrayToString(byte[] characters)
    {
        UTF8Encoding encoding = new UTF8Encoding();
        string constructedString = encoding.GetString(characters);
        return (constructedString);
    }

i love chocolate
 
That square box is the UTF-8 byte-order-mark (BOM), like alphanytz said. Just pass in false to the constructor.

By using the UnicodeEncoding like you are, you're converting your UTF-8 (a multi-byte encoding that is 8-bits wide) to UTF-16 (a 16-bit wide encoding). You'll get a BOM in this case too, but apps like Notepad will hide it from you. In order to *really* see what's being produced, you need a hex editor to look at the raw bytes.

Chip H.




____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top