在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的限制?
答案 0 :(得分:3)
老实说,我不确定答案是什么。您是否尝试删除服务引用并从头开始重新创建它?这似乎是尝试修复它的最直接的方法,特别是因为你做了改变。
我知道你没有问这个问题,但是除此之外,我个人已经完全放弃了在visual studio中使用服务参考功能。这是一个很好的video,描述了它是多么容易做,只要你愿意稍微重构你的代码。由于听起来你负责WCF客户端和服务器,我认为你会从Miguel倡导的方法中获益匪浅。
编辑:
在回应John Saunder的评论时,如果您负责客户端和服务器,那么在我看来,您最好将合同(服务和数据合同)重新分解为单个程序集在客户端和服务器之间共享。当您添加/更新服务引用时,所做的就是为客户端生成代码生成的 copy 这些合同,然后添加代理的样板代码。所以从本质上讲,你对这些接口和类有两个独立但相同的定义,一个在服务器端,一个在客户端。
我之所以迁移是因为我在Windows服务中托管了WCF服务。客户在整个项目中使用此服务的四个独立程序集。每次我更改WCF服务的服务/数据协定时,我都必须更新使用WCF服务的四个程序集中的服务引用。通过将这些契约重构为单个共享程序集,我更新了程序集,重新编译(无论如何我都要做),我已经准备好了。我不再需要记住需要更新的程序集。
我意识到网络上的很多例子都谈到了使用svcutil工具的简单性,但就我而言,这是不必要的开销。
看一下视频并自己判断。
答案 1 :(得分:0)
确保所有datacontract仅包含那些具有返回类型作为基本数据类型或任何其他dataContact的属性。需要XMLSerialization的数据类型(如DataSet和DataType)会将您的datacontract转换为MessegeContract,代码生成器只显示与注释相同的消息。