WCF: Сериализация и Десериализация универсальных наборов

У меня есть класс Команда, которая содержит универсальный список:

[DataContract(Name = "TeamDTO", IsReference = true)]
public class Team
{
    [DataMember]
    private IList<Person> members = new List<Person>();

    public Team()
    {
        Init();
    }

    private void Init()
    {
        members = new List<Person>();
    }

    [System.Runtime.Serialization.OnDeserializing]
    protected void OnDeserializing(StreamingContext ctx)
    {
        Log("OnDeserializing of Team called");
        Init();
        if (members != null) Log(members.ToString());
    }

    [System.Runtime.Serialization.OnSerializing]
    private void OnSerializing(StreamingContext ctx)
    {
        Log("OnSerializing of Team called");
        if (members != null) Log(members.ToString());
    }

    [System.Runtime.Serialization.OnDeserialized]
    protected void OnDeserialized(StreamingContext ctx)
    {
        Log("OnDeserialized of Team called");
        if (members != null) Log(members.ToString());
    }

    [System.Runtime.Serialization.OnSerialized]
    private void OnSerialized(StreamingContext ctx)
    {
        Log("OnSerialized of Team called");
        Log(members.ToString());
    }

Когда я использую этот класс в сервисе WCF, я получаю следующий вывод журнала

OnSerializing of Team called    
System.Collections.Generic.List 1[XXX.Person]

OnSerialized of Team called    
System.Collections.Generic.List 1[XXX.Person]

OnDeserializing of Team called    
System.Collections.Generic.List 1[XXX.Person]

OnDeserialized of Team called    
XXX.Person[]

После десериализации members Массив и больше универсальный список, хотя тип поля является IList <> (?!) Когда я пытаюсь передать этот объект обратно по сервису WCF, я производил журнал

OnSerializing of Team called
XXX.Person[]

После того, как этот мой модульный тест отказывает с Системой. ExecutionEngineException, что означает сервис WCF, не может сериализировать массив. (возможно, потому что это ожидало IList <>),

Так, мой вопрос: кто-либо знает, почему тип моего IList <> является массивом после десериализации и почему я не могу сериализировать свой объект Команды еще после этого?

Спасибо

20
задан Fabiano 1 April 2010 в 23:33
поделиться

3 ответа

Вы столкнулись с одной из ошибок DataContractSerializer .

Исправление: Измените объявление частного члена на:

[DataMember]
private List<Person> members = new List<Person>();

ИЛИ измените свойство на:

[DataMember()]
public IList<Person> Feedback {
    get { return m_Feedback; }
    set {
        if ((value != null)) {
            m_Feedback = new List<Person>(value);

        } else {
            m_Feedback = new List<Person>();
        }
    }
}

И это будет работать. Ошибка Microsoft Connect здесь

Эта проблема возникает, когда вы десериализуете объект с помощью IList DataMember, а затем пытаетесь сериализовать тот же экземпляр еще раз.

Если вы хотите увидеть что-нибудь интересное:

using System;
using System.Collections.Generic;

class TestArrayAncestry
{
    static void Main(string[] args)
    {
        int[] values = new[] { 1, 2, 3 };        
        Console.WriteLine("int[] is IList<int>: {0}", values is IList<int>);
    }
}

Он напечатает int [] is IList : True .

Я подозреваю, что это, возможно, причина, по которой вы видите, что он возвращается в виде массива после десериализации, но это довольно неинтуитивно.

Если вы вызываете метод Add () для IList массива, он вызывает исключение NotSupportedException .

Одна из тех причуд .NET.

22
ответ дан 30 November 2019 в 00:51
поделиться

Похоже, ваша ссылка на службу WCF создает прокси-класс, а не использует существующий тип. Прокси-классы могут использовать только простые массивы, а не какие-либо специфические для .NET типы, такие как общий список.

Чтобы избежать этого преобразования прокси-класса, на экране «Добавить ссылку на службу» нажмите кнопку «Дополнительно», а затем убедитесь, что установлен флажок «Повторное использование типов в ссылочных сборках». Это обеспечит использование существующего класса (с универсальным списком) при сериализации и десериализации объекта.

1
ответ дан 30 November 2019 в 00:51
поделиться

Я получил эту ошибку при транспортировке IList, считанного из базы данных через LINQ. WCF размещался в IIS 7 на Windows Server 2008 x64.

Сбой пула приложений без предупреждений.

[ServiceBehavior]
public class Webservice : IWebservice
{

    public IList<object> GetObjects()
    {
        return Database.Instance.GetObjects();
    }
}

Это не совсем та же проблема, но причина может быть та же.

Решением было установить исправление MS KB973110 http://support.microsoft.com/kb/971030/en-us

2
ответ дан 30 November 2019 в 00:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: