WCF服务未公开的类型

问题描述:

我有一个小型测试Web服务来模拟我在一个真实世界的应用程序中注意到的奇怪事情。由于演示显示与应用程序相同的行为,因此我将使用该演示以简化操作。我可以看到它是由VS2008创建的默认WCF服务,但我在底部添加了一个新的公共方法(GetOtherType())和两个新类(SomeOtherType和SomeComplexType)。SomeOtherType管理型SomeComplexType的泛型列表WCF服务未公开的类型

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 

namespace WCFServiceTest 
{ 

    [ServiceContract] 
    public interface IService1 
    { 
     [OperationContract] 
     string GetData(int value); 

     [OperationContract] 
     CompositeType GetDataUsingDataContract(CompositeType composite); 

     [OperationContract] 
     SomeOtherType GetOtherType(); 

    } 


    [DataContract] 
    public class CompositeType 
    { 
     bool boolValue = true; 
     string stringValue = "Hello "; 

     [DataMember] 
     public bool BoolValue 
     { 
      get { return boolValue; } 
      set { boolValue = value; } 
     } 

     [DataMember] 
     public string StringValue 
     { 
      get { return stringValue; } 
      set { stringValue = value; } 
     } 
    } 

    [DataContract] 
    public class SomeOtherType 
    { 
     public List<SomeComplexType> Items { get; set; }  
    } 

    [DataContract] 
    public class SomeComplexType 
    { 

    } 
} 

我的服务如下

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 

namespace WCFServiceTest 
{ 

    public class Service1 : IService1 
    { 


     #region IService1 Members 

     public string GetData(int value) 
     { 
      throw new NotImplementedException(); 
     } 

     public CompositeType GetDataUsingDataContract(CompositeType composite) 
     { 
      throw new NotImplementedException(); 
     } 

     #endregion 

     #region IService1 Members 


     public SomeOtherType GetOtherType() 
     { 
      throw new NotImplementedException(); 
     } 

     #endregion 
    } 
} 

我的问题是实现,如果我有一个服务引用在ASP这项服务。 NET Web应用程序,我可以没有通过intellisense看到SomeComplexType。错误与类型或名称空间无关。但是,可以找到SomeOtherType(我假设该类型是一个公共方法的返回类型)。

我是否正确思考如果该类型没有在我的一个公共方法(返回类型或参数)的方法签名中出现,我无法公开WCF服务的类型?如果是这样,我将如何迭代客户端上的SomeOtherType实例中的Items?

很多谢谢,我希望这很清楚。

西蒙

+0

确实很奇怪。你为什么要在一个地方定义数据合同和服务本身?此外,这是在SVC文件或一些单独的.cs文件? – Slavo 2010-03-24 13:39:01

我的问题是,如果我 包括ASP.NET Web应用程序的服务引用这个 服务, 我无法通过 intellisense查看SomeComplexType。该错误与 类型或名称空间无法找到有关。 但是,SomeOtherType可以找到 (我假设这种类型是从一种公共方法返回 类型)。

我是正确的思维,我不能暴露 类型从一个WCF服务,如果该类型 在我的公开方法 (无论返回类型或参数)一个方法 签名没有特色?如果 那么,我将如何能够遍历 客户端上的SomeOtherType实例内的项目 ?

你是绝对正确的 - 你SomeComplexType是从来没有在任何的服务方法使用,并且它也从来没有标记为[数据成员在任何确实用作服务方法的参数的类型。因此,从WCF的角度来看,这不是必需的,并且不会显示在WSDL/XSD中。

正如格雷厄姆所指出的 - 您使用的是在一个SomeComplexType地方:

[DataContract] 
public class SomeOtherType 
{ 
    public List<SomeComplexType> Items { get; set; }  
} 

但由于Items元素没有标记为[DataMember],它(因此它使用的类型)不会包含在您的服务的WSDL/XSD中。由于Items未被标记为DataMember,因此它们也不会在您的序列化WCF消息中,因此您不需要遍历此集合:-)

因此,最有可能的是,您真正想要的是只需将[DataMember]属性添加到您的Items属性中;那么它将包含在WSDL/XSD中,SomeComplexType也将包含在内。

+0

感谢Graham和marc_s。两人都回答了这个问题,但将marc_s标记为答案,因为更完整的答案可能对其他人有帮助。再次感谢大家 – 2010-03-25 09:56:24

我不在此主题的所有方面的专家,所以就像在蓝色拍:空DataContracts被丢弃WCF?尝试暴露ComplexDataType中的任何内容(有些int就足够了),看看它是否会改变任何内容。

此外,我相信你可以使用内置的wcftestclient(你需要为此打开元数据交换)来验证类型的可用性。

看起来你需要在你的SomeOtherType.Items财产[DataMember]属性,即

[DataMember] 
public List<SomeComplexType> Items { get; set; } 

我们可以在服务中使用已知类型,以便在直接或间接地在操作合同签名中未使用该类及其成员时暴露该类及其成员。

对于您只希望在客户端可用的类型(即使未使用它),在属性类下方可方便地在客户端使用它。

[KnownType(typeof(SomeComplexType))]