从“更新服务参考”中获取错误的生成代码

时间:2009-08-18 14:30:35

标签: .net visual-studio wcf xml-serialization datacontractserializer

在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的限制?

2 个答案:

答案 0 :(得分:3)

老实说,我不确定答案是什么。您是否尝试删除服务引用并从头开始重新创建它?这似乎是尝试修复它的最直接的方法,特别是因为你做了改变。

我知道你没有问这个问题,但是除此之外,我个人已经完全放弃了在visual studio中使用服务参考功能。这是一个很好的video,描述了它是多么容易做,只要你愿意稍微重构你的代码。由于听起来你负责WCF客户端和服务器,我认为你会从Miguel倡导的方法中获益匪浅。

编辑:

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

我之所以迁移是因为我在Windows服务中托管了WCF服务。客户在整个项目中使用此服务的四个独立程序集。每次我更改WCF服务的服务/数据协定时,我都必须更新使用WCF服务的四个程序集中的服务引用。通过将这些契约重构为单个共享程序集,我更新了程序集,重新编译(无论如何我都要做),我已经准备好了。我不再需要记住需要更新的程序集。

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

看一下视频并自己判断。

答案 1 :(得分:0)

确保所有datacontract仅包含那些具有返回类型作为基本数据类型或任何其他dataContact的属性。需要XMLSerialization的数据类型(如DataSet和DataType)会将您的datacontract转换为MessegeContract,代码生成器只显示与注释相同的消息。