OK、これはVS 2013で正常に機能しました。問題が発生したことを2015年にアップグレードした後で初めてプロジェクトを開始したときです。VS 2015でのサービス参照の生成中にエラーが発生する
簡単に言えば、WCF Proxy GeneratorにプロパティタイプのCLR名前空間を指定するように指示する方法がわかりません。明らかにこれは今必要です。ここで
は私の契約です: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プロパティのクラスです:
<ServiceContract>
Friend Interface IService
<OperationContract> Function CheckFiles() As List(Of String)
<OperationContract> Function CreateBackup(AllFiles As List(Of String)) As BackupResult
End Interface
ここでクラスが返されます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
クラスは生成されません。以下の警告は表示されず、すべてが機能します。
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
プロキシクラスでは、このすべての結果が生成されていない:
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年に取得しています警告だ:私が必要)
をここで生成されたコードです。
私はthisとthisを読んできましたが、それらはサービスレベルのカスタムネームスペースに関係しているようです。私は、CLRタイプとしてプロパティタイプを認識し、それ自身のDirectoryInfo
クラスを生成しないようにジェネレータに指示する方法を知る必要があります。
問題は、ISerializableフィールドをサポートしていませんDataContractSerializerを、使用しているという事実にあります。プリミティブと他のデータ変換のみ。代わりに、XmlSerializerを使用して、複雑さに対処するか、フィールドの型を文字列に変更する必要があります(これは意味がありますが、そうではありません)。 – jessehouwing
@jessehouwing:私は 'XmlSerializerFormat'でより多くのログジャムを実行しました。その結果、文字列を使い、一方の端で解体し、もう一方の端で再構築しました。だから、私はWCFとSystem.IOの将来を考えています。なぜ私はそれをマークすることができる答えにしないでください? (ちなみに、お気に入りのスクラムフォーラムは何ですか?) – InteXX