我们的 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
正是出于这个原因,我提供了一个。
客户端代理类MyEnumHere
在 Reference.cs 文件中确实有一个枚举;问题是ParameterCollection
该类没有KnownTypeAttribute
为它生成 s 。
我求助于手动编辑,并在生成的 Reference.cs 文件中包含以下几行:
//>
[KnownTypeAttribute(typeof(MyEnumHere))]
[KnownTypeAttribute(typeof(MyEnumHere?))]
[KnownTypeAttribute(typeof(MyClassHere))]
[KnownTypeAttribute(typeof(MyClassListHere))]
//<
public class ParameterCollection : Dictionary<string, object> { /* ... */ }
手工编辑生成的文件是可怕的。但这使客户工作。我究竟做错了什么?如何定义我的服务对象,以便生成的 VS 代理类从一开始就正确?
谢谢你的时间。