代码之家  ›  专栏  ›  技术社区  ›  quip

WCF向客户端发送对象时出现问题

  •  1
  • quip  · 技术社区  · 16 年前

    从使用.Net远程处理转换为WCF。WCF服务器上的大多数方法都工作正常,但遇到了一个今天不工作的方法。

    [ServiceContract]
    public interface IMyService
    {
      [OperationContract]
      generated.Response.ACS_Response Check(generated.Request.ACS_Request request);
    }
    

    ACS_Response和ACS_request的类是根据XSD文件使用XSD.exe生成的。这些类驻留在WCF客户端和WCF主机都引用的Api程序集中。

    我打开了WCF的跟踪,并看到SerializationException说:

    Type 'Api.generated.Response.ACS_ResponseQuestion'
    with data contract name 'ACS_ResponseQuestion:http://...' is
    not expected.  Add any types not known statically.........
    

    问题

    首先,我很困惑,因为我能够成功地发送一个请求对象,所以看起来基础工作正常。

    第三,主机和客户端都引用定义这些类的相同Api程序集,因此服务器和客户端都知道这些类。

    3 回复  |  直到 16 年前
        1
  •  2
  •   Philip Wallace    16 年前

    我相信是因为 Api.generated.Response.ACS_ResponseQuestion

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

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

    [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;
    }
    
        2
  •  1
  •   Aaron Fischer    16 年前

    ServiceKnownType 这会让你省去一些悲伤。注册一个基类对您来说非常简单,它将扫描程序集以查找从基类继承的所有类。