2009-08-18 3 views
6

У меня есть объект, который имеет общий IList в нем, что возвращается из метода веб-службы WCF:WCF IList Сериализация Выпуск

[DataContract(Name = "PageableList_Of_{0}")] 
public class PageableResults<T> 
{ 
    [DataMember] 
    public IList<T> Items { get; set; } 
    [DataMember] 
    public int TotalRows { get; set; } 
} 

[OperationContract] 
PageableResults<ContentItem> ListCI(); 

Когда я называю этот метод на службу он выполняет весь метод штрафа , но в самом конце он генерирует исключение System.ExecutionEngineException без исключения InnerException. Я попытался вернуть конкретный список объектов и, похоже, работает, но, к сожалению, мне нужно найти временное решение, чтобы вернуть IList. Есть ли какие-либо атрибуты, которые мне нужно внести, чтобы решить эту проблему?

+0

Вы говорите «когда я вызываю этот метод на службе» - действительно ли ошибка при десериализации результата? –

+0

Я думаю, что это происходит на стороне обслуживания, когда он переходит к сериализации объекта, поскольку он срабатывает, когда я выхожу из метода службы, но в исключении нет трассировки стека, поэтому я не могу быть положительным. – Nick

ответ

1

Вы должны добавить атрибут KnownTypes по определению класса выше вашего определения класса для каждого использования T. Как это:


[KnownType(typeof(ContentItem))] 
[DataContract(Name = "PageableList_Of_{0}")] 
public class PageableResults<T> 
{ 
    [DataMember] 
    public IList<T> Items { get; set; } 
    [DataMember] 
    public int TotalRows { get; set; } 
} 

[OperationContract] 
PageableResults ListCI(); 

В качестве альтернативы вы можете определить свой собственный класс коллекции, который имеет свойство TotalRows , как это:


[KnownType(typeof(ContentItem))] 
[DataContract(Name = "PageableList_Of_{0}")] 
public class PageableResults<T> : EntityCollectionWorkaround<T> 
{ 
    [DataMember] 
    public int TotalRows { get; set; } 
} 

Где EntityCollectionWorkaround определяется здесь:
http://borismod.blogspot.com/2009/06/v2-wcf-collectiondatacontract-and.html

1

Я не думаю, что вы можете это сделать. Как сериализатор знает, к чему десериализовать? Многие вещи могут реализовать IList, а интерфейс не имеет конструктора.

+0

Кажется, что работает отлично при использовании netTcpBinding, но не с WSHttpBinding – Nick

+0

, каков его базовый тип десериализации? Я не вижу, как это может сработать, если это просто случайный выбор контейнера, который реализует IList и хранит их там. – Steve

1

Оказывается, что это ошибка в WCF, которая фиксируется в .NET 4. Тем не менее, есть несколько обходных путей, перечисленных в этой теме:
http://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=433569

Резюме:
- Put сборки, которые содержат DataContracts в GAC.
- Установите LoaderOptimization в SingleDomain.

0

Наследовать от PageableResults, чтобы создать закрытый общий подкласс, в вашем случае PageableContentItem или что-то в этом роде, и использовать это как возвращаемый тип. Обычно с web-сервисами используется XML-сериализатор, и он должен знать все заранее, поэтому вы также не можете возвращать типы интерфейсов.

public class PageableContentItem 
     : PageableResults<ContentItem> 
    { 

    } 

[OperationContract] 
PageableContentItem ListCI(); 
Смежные вопросы