WCF问题将对象发送到客户端

时间:2009-11-13 19:03:24

标签: c# wcf serialization

背景

使用.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程序集,因此服务器和客户端都知道它们。

3 个答案:

答案 0 :(得分:2)

我认为这是因为Api.generated.Response.ACS_ResponseQuestion未在合同(API)中使用,因此它不会自动标记为已知类型。

阅读这些文章,他们应该解释一切:

  1. Known Types
  2. Data Contract Known Types
  3. Understanding Known Types

  4. 快速解决方案:尝试将此添加到实现接口的类:

    [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的方式:

http://www.dnrtv.com/default.aspx?showNum=122