Cannot deserialize with XMLSerializer result from WCF webservice
Asked Answered
B

3

5

Here is the code trying from compact framework to get http service..

    List<Table> tables;
    using (Stream r = response.GetResponseStream())
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Table),"http://schemas.datacontract.org/2004/07/");
        tables=(List<Table>) serializer.Deserialize(r);
    }

   response.Close();

It fails with {"There is an error in XML document (1, 2)."}

{"<ArrayOfTable xmlns='http://schemas.datacontract.org/2004/07/WpfApplication1.Data.Model'> was not expected."}

Table namespace is the same... I dont know whats wrong there...

UPDATE

Problem was that i had typeof(Table) not typeof(List<Table>) which works partially.. No error but created tables values are null!

Bar answered 24/8, 2011 at 16:7 Comment(1)
I believe that the second parameter specifies the default namespace for serialization, not for deserialization.Soilasoilage
F
5

The second parameter on the XmlSerializer constructor works for both serializing and deserializing. So, on the second parameter (the namespace) should be the same to the one being received. So you'll end up having:

XmlSerializer serializer = new XmlSerializer(typeof(Table),"http://schemas.datacontract.org/2004/07/WpfApplication1.Data.Model")

Note the "WpfApplication1.Data.Model" at the end of the namespace string.

One way to get rid of the namespace thing. Is to specify on your model class (Table) that it should not use a namespace:

[DataContract(Namespace = "")]
public class Table { ... }

That way you don't need to specify the namespace for deserialization.

Hope it helps!

Furman answered 1/11, 2011 at 6:58 Comment(0)
K
4

Not sure if this will help, but we had a similar issue. Instead of decorating thousands of data elements with DataContract/DataMember attributes and using the (default) DataContractSerializer, we found that if our WCF service used the XmlSerializerFormat instead, we could easily deserialize our objects.

[System.ServiceModel.ServiceContract]
public interface IRestService
{
    [System.ServiceModel.OperationContract]
    // Added this attribute to use XmlSerializer instead of DataContractSerializer
    [System.ServiceModel.XmlSerializerFormat(
        Style=System.ServiceModel.OperationFormatStyle.Document)]
    [System.ServiceModel.Web.WebGet(
        ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Xml,
        UriTemplate = "xml/objects/{myObjectIdentifier}")]
    MyObject GetMyObject(int myObjectIdentifier);
}

This is how we're deserializing the objects:

public static T DeserializeTypedObjectFromXmlString<T>(string input)
{
    T result;

    try
    {
        System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(T));
        using (System.IO.TextReader textReader = new System.IO.StringReader(input))
        {
            result = (T)xs.Deserialize(textReader);
        }
    }
    catch
    {
        throw;
    }

    return result;
}
Kippar answered 30/11, 2011 at 22:38 Comment(0)
A
0

Instead of returning a List return an object that has a single property of List.

Agreed answered 24/8, 2011 at 17:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.