使用WCF,LINQ,JSON时,无法序列化'System.Linq.Enumerable ...'类型的参数

时间:2010-01-15 01:39:02

标签: linq wcf json linq-to-objects

我有一个WCF服务。它使用Linq-to-objects从Dictionary中进行选择。对象类型很简单:

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 个答案:

答案 0 :(得分:11)

不,必须从Web服务返回具体类。创建返回类型列表并完成它。

答案 1 :(得分:5)

您必须使用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);
    }
}

基本上你需要知道你返回的具体类型。很简单。

答案 2 :(得分:1)

您需要将可互操作的集合传递给WCF方法或从WCF方法传递。

WCF在简单类型和数组方面表现最佳。

从客户端传入一个数组,然后将其转换为服务中的IEnumerable。

像IEnumerable这样的东西是不可互操作的,这就是WCF试图成为的东西。

可能有一种方法可以解决已知类型,但我总是努力使我的组件尽可能灵活。