У меня есть класс Команда, которая содержит универсальный список:
[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 <> является массивом после десериализации и почему я не могу сериализировать свой объект Команды еще после этого?
Спасибо
Вы столкнулись с одной из ошибок 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
.
Я подозреваю, что это, возможно, причина, по которой вы видите, что он возвращается в виде массива после десериализации, но это довольно неинтуитивно.
Если вы вызываете метод Add () для IList
массива, он вызывает исключение NotSupportedException
.
Одна из тех причуд .NET.
Похоже, ваша ссылка на службу WCF создает прокси-класс, а не использует существующий тип. Прокси-классы могут использовать только простые массивы, а не какие-либо специфические для .NET типы, такие как общий список.
Чтобы избежать этого преобразования прокси-класса, на экране «Добавить ссылку на службу» нажмите кнопку «Дополнительно», а затем убедитесь, что установлен флажок «Повторное использование типов в ссылочных сборках». Это обеспечит использование существующего класса (с универсальным списком) при сериализации и десериализации объекта.
Я получил эту ошибку при транспортировке 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