Невозможно сериализовать параметр типа 'System.Linq.Enumerable... ' при использовании WCF, LINQ, JSON.
У меня есть служба WCF. Он использует Linq-to-objects для выбора из словаря. Тип объекта прост:
public class User
{
public Guid Id;
public String Name;
}
Существует коллекция хранится в Dictionary<Guid,User>
,
Я хочу иметь WCF OperationContract
метод как это:
public IEnumerable<Guid> GetAllUsers()
{
var selection = from user in list.Values
select user.Id;
return selection;
}
Он хорошо компилируется, но когда я запускаю его, я получаю:
Сервер обнаружил ошибку при обработке запроса. Сообщение об исключении: "Невозможно сериализовать параметр типа" System.Linq.Enumerable + WhereSelectEnumerableIterator
2[Cheeso.Samples.Webservices._2010.Jan.User,System.Guid]' (for operation 'GetAllUsers', contract 'IJsonService') because it is not the exact type 'System.Collections.Generic.IEnumerable
1 [System.Guid] 'в сигнатуре метода и отсутствует в коллекции известных типов. Чтобы сериализовать параметр, добавьте тип в коллекцию известных типов для операции, используя ServiceKnownTypeAttribute. '. Смотрите журналы сервера для более подробной информации.
Как я могу заставить выбор быть IEnumerable<Guid>
?
РЕДАКТИРОВАТЬ
Если я модифицирую код, чтобы сделать это, он работает хорошо - хорошая совместимость.
public List<Guid> GetAllUsers()
{
var selection = from user in list.Values
select user.Id;
return new List<Guid>(selection);
}
Есть ли способ для меня, чтобы избежать создания / создания List<T>
?
3 ответа
Нет, нужно возвращать конкретный класс из веб-службы. Сделайте возвращаемый тип List и покончите с этим.
Вы должны использовать атрибут ServiceKnownTypes.
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace Test.Service
{
[ServiceContract(Name = "Service", Namespace = "")]
public interface IService
{
[OperationContract]
[WebInvoke(
Method = "GET",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
[ServiceKnownType(typeof(List<EventData>))]
IEnumerable<EventData> Method(Guid userId);
}
}
По сути, вам нужно знать конкретный тип того, что вы возвращаете. Довольно просто
Вы должны передавать совместимые коллекции в и из ваших методов WCF.
WCF лучше всего работает с простыми типами и массивами.
Передайте массив от вашего клиента, а затем превратите его в IEnumerable в службе.
Такие вещи, как IEnumerable, не являются совместимыми, что и пытается сделать WCF.
Может быть способ обойти это с известными типами, но я всегда стремлюсь сделать свои компоненты максимально гибкими.