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。有谁知道我怎么能弄清楚什么在我的代码(可能在类事)违反DataContractSerializer的限制?

+0

查看生成的代码中的注释。他们告诉你什么是错的。 – 2009-08-18 14:32:21

+1

我不明白他们。什么是“参数模式”?它应该在哪里获取架构信息? XmlElementAttribute应该告诉我什么?我用google搜索无济于事。 – 2009-08-18 14:40:18

+0

注意,例如,GetThing(Guid)在接口中,但生成的客户端具有GetThing(String)。我也无法确定这一部分。 – 2009-08-18 14:53:31

回答

3

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

我知道你没有问过这个,但作为一个旁白,我个人已经远离在Visual Studio中完全使用服务引用功能。这是一个很好的video,它描述了它是多么容易,只要你愿意重构一下你的代码。由于这听起来像你负责WCF客户端和服务器,我认为你会从Miguel所倡导的方法中获得巨大收益。

编辑:

针对约翰·Saunder的评论,如果你是负责在客户端和服务器,你会更好,在我看来,要重新因子的合同(服务和数据合同)集成到客户端和服务器之间共享的单个程序集中。当您添加/更新服务参考时,所做的只是为客户端生成这些合同的代码生成拷贝,然后为代理添加样板代码。所以实质上,你有两个独立但相同的接口和类的定义,一个在服务器端,另一个在客户端。

我之所以迁移这个原因是因为我有一个WCF服务托管在Windows服务中。在我的项目中,客户在四个独立的程序集中使用了此服务。每次我对WCF服务的服务/数据合同进行更改时,我都必须更新使用WCF服务的四个程序集中的服务引用。通过将这些契约重构为单一的共享程序集,我更新了该程序集,重新编译(我将不得不这样做),并且我准备好了。我不再需要记住哪些组件需要更新。

我意识到很多Web上的例子都谈论了使用svcutil工具的简单性,但在我的情况下,这是不必要的开销。

看看视频并为自己判断。

+0

我会建议对此,没有更好的理由。几乎所有在网络上找到的示例都将使用服务引用。 – 2009-08-18 22:17:41

+0

添加服务引用允许您使用共享程序集中的类型。只需点击“高级”按钮。 – 2009-08-19 22:01:42

+0

谢谢,马特 - 那个视频非常有帮助。即使我使用“简单”手动客户端创建(使用ChannelFactory方法),我认为在处理字典(字符串,TVal)时,我们会遇到序列化方式的问题。我计划从简单开始并从那里出发。 – 2009-08-20 02:00:39

0

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