Невозможно десериализовать результат XMLSerializer из веб-службы WCF. - PullRequest
5 голосов
/ 24 августа 2011

Вот код, пытающийся из компактной среды получить http-сервис.

    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();

Сбой при {{В XML-документе (1, 2) есть ошибка.)}

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

Пространство имен таблицы такое же ... Я не знаю, что там не так ...

UPDATE

Проблема заключалась в том, что у меня был typeof (Таблица), а не typeof (List<Table>), который работает частично. Нет ошибок, но значения созданных таблиц равны нулю!

Ответы [ 3 ]

5 голосов
/ 01 ноября 2011

Второй параметр в конструкторе XmlSerializer работает как для сериализации, так и для десериализации. Таким образом, второй параметр (пространство имен) должен совпадать с принимаемым. В итоге вы получите:

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

Обратите внимание на «WpfApplication1.Data.Model» в конце строки пространства имен.

Один из способов избавиться от вещи с пространством имен. Следует указать в классе вашей модели (Таблица), что он не должен использовать пространство имен:

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

Таким образом, вам не нужно указывать пространство имен для десериализации.

Надеюсь, это поможет!

4 голосов
/ 01 декабря 2011

Не уверен, поможет ли это, но у нас была похожая проблема.Вместо того, чтобы украшать тысячи элементов данных с помощью атрибутов DataContract / DataMember и использовать (по умолчанию) DataContractSerializer, мы обнаружили, что если бы наш сервис WCF использовал вместо этого XmlSerializerFormat, мы могли бы легко десериализовать наши объекты.

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

Этокак мы десериализуем объекты:

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;
}
0 голосов
/ 24 августа 2011

Вместо возврата List верните объект, который имеет единственное свойство List.

...