1

在 VB.NET(使用 Visual Studio 2008)中,我的 WCF 服务有一个类似的接口:

<ServiceContract()> _
Public Interface IThingService
    <OperationContract()> _
    Function GetThingByNumber(ByVal thingNumber As MyKeyClass) As Thing
    <OperationContract()> _
    Function GetThing(ByVal thingId As Guid) As Thing

    ' ...

End Interface

我最近更改了两个具有相似代码的项目,以使用 basicHttpBinding 而不是 wsHttpBinding。一切都在服务端编译得很好。现在,在客户端应用程序中,我选择“更新服务参考”。在一个项目中,我生成的 reference.vb 似乎是正确的——不到 100 行,每种方法都有简单的包装器。但是,另一方面,生成的 reference.vb 似乎无法理解服务是什么。我得到一个超过 1000 行的 reference.vb,如下所示:

 '------------------------------------------------------------------------------
 ' <auto-generated>
 '     This code was generated by a tool.
 '     Runtime Version:2.0.50727.3053
 '
 '     Changes to this file may cause incorrect behavior and will be lost if
 '     the code is regenerated.
 ' </auto-generated>
 '------------------------------------------------------------------------------
 Option Strict On
 Option Explicit On
 Imports System.Data
 Namespace ThingService

 <System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0"),  _
 System.ServiceModel.ServiceContractAttribute(ConfigurationName:="GetThingByVersion.IGetThingByVersion")>  _
 Public Interface IThingService

    'CODEGEN: Parameter 'GetThingByNumberResult' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlElementAttribute'.
    <System.ServiceModel.OperationContractAttribute(Action:="http://tempuri.org/ThingService/GetThingByVersion", ReplyAction:="http://tempuri.org/ hingService/GetThingByVersionResponse"),  _
     System.ServiceModel.XmlSerializerFormatAttribute()>  _
    Function GetThingByNumber(ByVal request As ThingService.GetThingByVersionRequest) As ThingService.GetThingByVersionResponse

    'CODEGEN: Parameter 'GetThingResult' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlElementAttribute'.
    <System.ServiceModel.OperationContractAttribute(Action:="http://tempuri.org/ThingService/GetThing", ReplyAction:="http://tempuri.org/ThingService/GetThingResponse"),  _
     System.ServiceModel.XmlSerializerFormatAttribute()>  _
    Function GetThing(ByVal request As ThingService.GetThingRequest) As ThingService.GetThingResponse
'...
End Interface

 '''<remarks/>
 <System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082"),  _
 System.SerializableAttribute(),  _
 System.Diagnostics.DebuggerStepThroughAttribute(),  _
 System.ComponentModel.DesignerCategoryAttribute("code"),  _
 System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://schemas.datacontract.org/2004/07/ThingLibraryCore")>  _
 Partial Public Class MyKeyClass
    Inherits Object
    Implements System.ComponentModel.INotifyPropertyChanged

    Private concatenatedThingNumberField As String
    Private ThingNumberField As Integer
    Private ThingNumberFieldSpecified As Boolean

 '... goes on and on...

就好像生成的代码对我的实际服务接口一无所知。知道如何解决这个问题吗?提前致谢。

编辑:看起来我需要确保服务器可以使用 DataContractSerializer 而不是 XmlSerializer:请参阅http://blogs.msdn.com/sonuarora/archive/2007/06/16/contract-generation-from-wsdl- xml-schema-datacontractserializer-vs-xmlserializer.aspx。有谁知道我如何弄清楚我的代码(可能在 Class Thing 中)违反了 DataContractSerializer 的限制?

4

2 回答 2

3

老实说,我不确定答案是什么。您是否尝试过删除服务引用并从头开始重新创建它?这似乎是尝试修复它的最直接方法,尤其是在您进行了更改之后。

我知道你没有问这个,但顺便说一句,我个人已经完全放弃了在 Visual Studio 中使用服务引用功能。这是一个很好的视频,它描述了它是多么容易,只要你愿意稍微重构你的代码。因为听起来您同时负责 WCF 客户端和服务器,所以我认为您将从 Miguel 倡导的方法中受益匪浅。

编辑:

针对 John Saunder 的评论,如果您同时负责客户端和服务器,那么在我看来,您最好将合同(服务和数据合同)重新分解为一个共享的程序集客户端和服务器之间。当您添加/更新服务引用时,所做的只是为客户端制作这些合同的代码生成副本,然后为代理添加样板代码。所以本质上,这些接口和类有两个独立但相同的定义,一个在服务器端,一个在客户端。

我从这样做迁移的原因是因为我在 Windows 服务中托管了 WCF 服务。在我的整个项目中,客户在四个单独的程序集中使用了此服务。每次对 WCF 服务的服务/数据合同进行更改时,我都必须更新使用 WCF 服务的四个程序集中的服务引用。通过将这些合同重构为单个共享程序集,我更新了该程序集,重新编译(无论如何我都必须这样做),然后我就可以开始了。我不再需要记住哪些程序集需要更新。

我意识到网络上的许多示例都在谈论使用 svcutil 工具的简单性,但就我而言,这是不必要的开销。

看看视频并自己判断。

于 2009-08-18T21:53:02.380 回答
0

确保您的所有数据合同仅包含返回类型为原始数据类型或任何其他 dataContact 的属性。需要 XMLSerialization 的 DataSet 和 DataType 等数据类型会将您的数据合同转换为 MessegeContract,并且代码生成器仅显示与注释相同的消息。

于 2014-06-30T09:45:07.023 回答