【发布时间】:2012-06-20 04:20:00
【问题描述】:
我们的 WCF 服务只有一种方法:
[ServiceContract(Name = "Service", Namespace = "http://myservice/")]
[ServiceKnownType("GetServiceKnownTypes", typeof(Service))]
public interface IService {
Response Execute(Request request);
}
public class Service : IService {
public static IEnumerable<Type> GetServiceKnownTypes(ICustomAttributeProvider provider) {
return KnownTypesResolver.GetKnownTypes();
}
public Response Execute(Request request) {
return new MyResponse { Result = MyEnumHere.FirstValue };
}
}
Request 和 Response 类都包含一个 ParameterCollection 成员。
[Serializable]
[CollectionDataContract(Name = "ParameterCollection", Namespace = "http://myservice/")]
[KnownType("GetKnownTypes")]
public class ParameterCollection : Dictionary<string, object> {
private static IEnumerable<Type> GetKnownTypes()
{
return KnownTypesResolver.GetKnownTypes();
}
}
Request 和 Response 的子类将它们的值存储到 ParameterCollection 值包中。
我正在使用 KnownTypesResolver 类来提供所有服务对象的类型信息。
public static class KnownTypesResolver {
public static IEnumerable<Type> GetKnownTypes()
{
var asm = typeof(IService).Assembly;
return asm
.GetAllDerivedTypesOf<Response>() // an extension method
.Concat(new Type[] {
typeof(MyEnumHere),
typeof(MyEnumHere?),
typeof(MyClassHere),
typeof(MyClassListHere),
});
}
}
如果我没记错的话,一切都应该有适当的类型信息,以便代理类生成工具在客户端生成定义良好的类。
但是,每当Response 子类之一(即MyResponse)包含诸如MyEnumHere 之类的枚举值时,WCF 就会开始抱怨反序列化程序不知道 MyEnumHere 值。它应该有。为此,我提供了KnownTypeAttribute。
客户端代理类在 Reference.cs 文件中确实有一个MyEnumHere 枚举;问题是ParameterCollection 类没有为它生成KnownTypeAttributes。
我采用了手工编辑,并在生成的 Reference.cs 文件中包含以下几行:
//>
[KnownTypeAttribute(typeof(MyEnumHere))]
[KnownTypeAttribute(typeof(MyEnumHere?))]
[KnownTypeAttribute(typeof(MyClassHere))]
[KnownTypeAttribute(typeof(MyClassListHere))]
//<
public class ParameterCollection : Dictionary<string, object> { /* ... */ }
手工编辑生成的文件太可怕了。但这使客户工作。我究竟做错了什么?如何定义我的服务对象,以便生成的 VS 代理类从一开始就正确?
感谢您的宝贵时间。
【问题讨论】:
标签: wcf .net-4.0 deserialization