我有一个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>
的创建/实例化吗?
答案 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试图成为的东西。
可能有一种方法可以解决已知类型,但我总是努力使我的组件尽可能灵活。