bwe*_*rks 6 c# generics wcf serialization serviceknowntype
我正在尝试实现一个服务契约,其中包含一个采用通用接口的方法,并且该泛型接口本身具有一个接口参数.我用ServiceKnownType修饰了服务接口,我用常规的KnownType修改了服务实现,并且我用常规的KnownType修饰了datacontract实现:
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallbacks))]
[ServiceKnownType(typeof(Batch<object>))]
[ServiceKnownType(typeof(Command))]
public interface IActions
{
[OperationContract]
IResponse TakeAction(IBatch<ICommand> commands);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant)]
[KnownType(typeof(Batch<object>))]
[KnownType(typeof(Command))]
internal class Actions : IActions
{
}
[DataContract]
[KnownType(typeof(Command))]
public class Batch<T> : IBatch<T>
{
}
Run Code Online (Sandbox Code Playgroud)
为了记录,我在那里有Batch,因为看起来你只能表示一次泛型类型的知识类型 - 它似乎发出BatchOfanyType,但我不知道如何处理它.
我得到的例外是"将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中."
有什么明显的我做错了吗?是否不支持接口的通用接口?为了记录我在这个项目的C#2.0和.NET 3.0上.
Tho*_*rin 12
如果你真的想要,你可以在服务合同定义中使用接口,只要你包括你正在做的已知类型(稍作调整,见下文).
显然,使用接口作为泛型类型参数使其成为C#3.0的桥梁.我将已知的type属性更改为
[ServiceKnownType(typeof(Batch<Command>))]
public interface IActions
{
}
Run Code Online (Sandbox Code Playgroud)
这使得它在某种程度上起作用.序列化和反序列化本身也可以,但是你遇到了这个例外:
无法将"Batch"1 [Command]'类型的对象强制转换为"IBatch`1 [ICommand]".
要使该转换工作,您需要语言支持泛型类型协方差,这是C#4.0中引入的.但是要在C#4.0中工作,你需要添加一个方差修饰符:
public interface IBatch<out T>
{
}
Run Code Online (Sandbox Code Playgroud)
然后它完美地工作...不幸的是你没有使用C#4.0.
关于在服务合同中使用接口的最后一件事:如果您正在从它们生成服务引用,它将键入所有接口参数object
,因为原始接口类型不是元数据的一部分.您可以通过程序集引用共享契约,或手动重构生成的代理来修复它,但总而言之,使用与WCF的接口可能比它的价值更麻烦.
归档时间: |
|
查看次数: |
6775 次 |
最近记录: |