使用.Net Remoting转换为WCF。 WCF服务器上的大多数方法都运行正常,但遇到了一个今天无效的方法。
这是服务合同:
[ServiceContract]
public interface IMyService
{
[OperationContract]
generated.Response.ACS_Response Check(generated.Request.ACS_Request request);
}
我在该界面上删除了其余的方法,因为它们正在工作。基本上,我正在尝试传入一个请求对象并返回一个响应对象。
ACS_Response和ACS_Reqeust的类是使用XSD.exe针对XSD文件生成的。这些类驻留在由WCF客户端和WCF主机引用的Api程序集中。
我能够调用WCF主机和Request对象,并且主机能够完成其工作。当主机尝试返回Response对象时,就是我遇到异常的地方。
我打开了WCF的跟踪并看到一个SerializationException:
Type 'Api.generated.Response.ACS_ResponseQuestion'
with data contract name 'ACS_ResponseQuestion:http://...' is
not expected. Add any types not known statically.........
首先,我很困惑,因为我能够成功发送一个Request对象,所以看起来基本工作正常。
其次,这个序列化正在.Net Remoting下工作。这些类都是由WSDL生成的,所以它们不应该是可序列化的吗?
第三,主机和客户端都引用了定义这些类的相同Api程序集,因此服务器和客户端都知道它们。
答案 0 :(得分:2)
我认为这是因为Api.generated.Response.ACS_ResponseQuestion
未在合同(API)中使用,因此它不会自动标记为已知类型。
阅读这些文章,他们应该解释一切:
快速解决方案:尝试将此添加到实现接口的类:
[KnownType(typeof(Api.generated.Response.ACS_ResponseQuestion))]
如果这不起作用,您可能必须将其声明为ServiceKnownType
:
// Define a service contract and apply the ServiceKnownTypeAttribute
// to specify types to include when generating client code.
// The types must have the DataContractAttribute and DataMemberAttribute
// applied to be serialized and deserialized. The attribute specifies the
// name of a method (GetKnownTypes) in a class (Helper) defined below.
[ServiceKnownType("GetKnownTypes", typeof(Helper))]
[ServiceContract()]
public interface ICatalog
{
// Any object type can be inserted into a Hashtable. The
// ServiceKnownTypeAttribute allows you to include those types
// with the client code.
[OperationContract]
Hashtable GetItems();
}
// This class has the method named GetKnownTypes that returns a generic IEnumerable.
static class Helper
{
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
{
System.Collections.Generic.List<System.Type> knownTypes =
new System.Collections.Generic.List<System.Type>();
// Add any types to include here.
knownTypes.Add(typeof(Widget));
knownTypes.Add(typeof(Machine));
return knownTypes;
}
}
[DataContract()]
public class Widget
{
[DataMember]
public string Id;
[DataMember]
public string Catalog;
}
[DataContract()]
public class Machine : Widget
{
[DataMember]
public string Maker;
}
答案 1 :(得分:1)
看看这个ServiceKnownType提供商它应该可以为您节省一些悲伤。您可以非常简单地注册基类型,它将扫描程序集以查找从基类继承的所有类。
答案 2 :(得分:0)
您正在引用客户端和服务器中的类,因此我建议您查看这种执行WCF的方式: