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,並且代碼生成器只顯示與註釋相同的信息。