好的,這在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
我的問題是,代理生成似乎並沒有能夠看到DirectoryInfo
在System.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
在代理類這所有的結果沒有產生。
我一直在閱讀this和this,但它們似乎與服務級別的自定義名稱空間有關。我需要知道如何告訴生成器將屬性類型識別爲CLR類型,而不是生成它自己的類別DirectoryInfo
。
問題在於這樣一個事實:你使用的DataContractSerializer,它不支持ISerializable的領域。只有基元和其他數據合約。你需要使用XmlSerializer來處理增加的複雜性,或者將字段的類型改爲字符串(這是有道理的,不是)。 – jessehouwing
@jessehouwing:我用'XmlSerializerFormat'碰到了更多的logjams,所以我最終使用了一個字符串,在一端解構並在另一端重構。所以感謝您的指點 - 我將在未來對WCF和'System.IO'保持警惕。爲什麼不把它作爲答案,以便我可以標記它? (在附註中,您最喜歡的Scrum論壇是什麼?) – InteXX