2016-04-01 20 views
0

好的,這在VS 2013中工作得很好。只有當我升級到2015年後重新開始工作時,問題才顯現出來。簡而言之,我不確定如何告訴WCF代理生成器爲屬性類型指定CLR名稱空間;顯然這是現在需要的。在VS 2015中生成服務引用時出錯

這裏是我的合同:

<ServiceContract> 
Friend Interface IService 
    <OperationContract> Function CheckFiles() As List(Of String) 
    <OperationContract> Function CreateBackup(AllFiles As List(Of String)) As BackupResult 
End Interface 

這裏是正在返回的類:

Public Class BackupResult 
    Public Property DbService As New DbService 
    Public Property TmpFolder As System.IO.DirectoryInfo ' <== Problem here ' 
    Public Property Chunks As Integer 
End Class 

而只是爲了清楚起見,這裏是爲DbService屬性的類(雖然它對於這個問題只有相關是表明它沒有任何System.IO引用)。

Public Class DbService 
    Public Property ErrorMessage As String = String.Empty 
    Public Property HasError As Boolean = False 
End Class 

我的問題是,代理生成似乎並沒有能夠看到DirectoryInfoSystem.IO命名空間,它不斷在服務的命名空間中生成它。 (當我註釋掉CreateBackup()函數時,重新運行服務並更新引用,不生成QbBackup.DirectoryInfo類。我沒有得到如下所示的警告,並且一切正常 - 就像它在2013年一樣 - 但當然沒有該屬性我需要)

下面是生成的代碼:

Namespace QbServer 

    ' ...           ' 
    '            ' 
    ' Other generated code here     ' 
    '            ' 
    ' ...           ' 
    '            ' 
    ' Note the generated DirectoryInfo class and ' 
    ' the BackupResult.TmpFolder property of type ' 
    ' QbServer.DirectoryInfo, when the namespace ' 
    ' should be System.IO instead     ' 
    '            ' 

    <System.Diagnostics.DebuggerStepThroughAttribute(), 
    System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"), 
    System.Runtime.Serialization.DataContractAttribute(Name:="BackupResult", [Namespace]:="http://schemas.datacontract.org/2004/07/Service"), 
    System.SerializableAttribute()> 
    Partial Public Class BackupResult 
    Inherits Object 
    Implements System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged 

    <System.NonSerializedAttribute()> 
    Private extensionDataField As System.Runtime.Serialization.ExtensionDataObject 

    <System.Runtime.Serialization.OptionalFieldAttribute()> 
    Private ChunksField As Integer 

    <System.Runtime.Serialization.OptionalFieldAttribute()> 
    Private DbServiceField As QbServer.DbService 

    <System.Runtime.Serialization.OptionalFieldAttribute()> 
    Private TmpFolderField As QbServer.DirectoryInfo 

    <Global.System.ComponentModel.BrowsableAttribute(False)> 
    Public Property ExtensionData() As System.Runtime.Serialization.ExtensionDataObject Implements System.Runtime.Serialization.IExtensibleDataObject.ExtensionData 
     Get 
     Return Me.extensionDataField 
     End Get 
     Set 
     Me.extensionDataField = Value 
     End Set 
    End Property 

    <System.Runtime.Serialization.DataMemberAttribute()> 
    Public Property Chunks() As Integer 
     Get 
     Return Me.ChunksField 
     End Get 
     Set 
     If (Me.ChunksField.Equals(Value) <> True) Then 
      Me.ChunksField = Value 
      Me.RaisePropertyChanged("Chunks") 
     End If 
     End Set 
    End Property 

    <System.Runtime.Serialization.DataMemberAttribute()> 
    Public Property DbService() As QbServer.DbService 
     Get 
     Return Me.DbServiceField 
     End Get 
     Set 
     If (Object.ReferenceEquals(Me.DbServiceField, Value) <> True) Then 
      Me.DbServiceField = Value 
      Me.RaisePropertyChanged("DbService") 
     End If 
     End Set 
    End Property 

    <System.Runtime.Serialization.DataMemberAttribute()> 
    Public Property TmpFolder() As QbServer.DirectoryInfo 
     Get 
     Return Me.TmpFolderField 
     End Get 
     Set 
     If (Object.ReferenceEquals(Me.TmpFolderField, Value) <> True) Then 
      Me.TmpFolderField = Value 
      Me.RaisePropertyChanged("TmpFolder") 
     End If 
     End Set 
    End Property 

    Public Event PropertyChanged As System.ComponentModel.PropertyChangedEventHandler Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged 

    Protected Sub RaisePropertyChanged(ByVal propertyName As String) 
     Dim propertyChanged As System.ComponentModel.PropertyChangedEventHandler = Me.PropertyChangedEvent 
     If (Not (propertyChanged) Is Nothing) Then 
     propertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(propertyName)) 
     End If 
    End Sub 
    End Class 

    <System.Diagnostics.DebuggerStepThroughAttribute(), 
    System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")> 
    Public Class DirectoryInfo 
    End Class 
End Namespace 

而這裏的我得到在Visual Studio 2015年警告:

Custom tool warning: Cannot import wsdl:portType Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter Error: ISerializable type with data contract name 'DirectoryInfo' in namespace ' http://schemas.datacontract.org/2004/07/System.IO ' cannot be imported. The data contract namespace cannot be customized for ISerializable types and the generated namespace 'QbServer' does not match the required CLR namespace 'System.IO'. Check if the required namespace has been mapped to a different data contract namespace and consider mapping it explicitly using the namespaces collection. XPath to Error Source: //wsdl:definitions[@targetNamespace=' http://tempuri.org/ ']/wsdl:portType[@name='IService'] ConsoleTest D:\Dev\Customers\OIT\Active\ConsoleTest\Service References\QbServer\Reference.svcmap 1

在代理類這所有的結果沒有產生。

我一直在閱讀thisthis,但它們似乎與服務級別的自定義名稱空間有關。我需要知道如何告訴生成器將屬性類型識別爲CLR類型,而不是生成它自己的類別DirectoryInfo

+0

問題在於這樣一個事實:你使用的DataContractSerializer,它不支持ISerializable的領域。只有基元和其他數據合約。你需要使用XmlSerializer來處理增加的複雜性,或者將字段的類型改爲字符串(這是有道理的,不是)。 – jessehouwing

+0

@jessehouwing:我用'XmlSerializerFormat'碰到了更多的logjams,所以我最終使用了一個字符串,在一端解構並在另一端重構。所以感謝您的指點 - 我將在未來對WCF和'System.IO'保持警惕。爲什麼不把它作爲答案,以便我可以標記它? (在附註中,您最喜歡的Scrum論壇是什麼?) – InteXX

回答

1

DataContractSerializer不支持類System.IO.DirectoryInfo。相反,您可以嘗試使用XmlSerializer,但您可能會遇到其他問題。

一個簡單的解決方案是添加一個string屬性,該屬性捕獲重新創建正確對象所需的數據。您也可以保留原始屬性,但請務必使用[NonSerialized]屬性標記它。

或者,您可以使用OnSerializingOnDeserializing屬性來確保DirectoryInfo值存儲在字符串字段中,並使DirectoryInfo在反序列化後恢復。

欲瞭解更多信息,請參閱:

+0

明白了,謝謝。這些回調很有趣 - 我會進一步調查。 – InteXX

+1

具體來說,我遇到了'XmlSerializer'和'DirectoryInfo'缺少無參數構造函數的問題。您所引用的博客文章討論了爲什麼'DirectoryInfo'與'DataContractSerializer'而不是'XmlSerializer'協同工作。這是一篇非常好的文章。 – InteXX

相關問題