2016-04-01 15 views
0

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 

私の問題は、プロキシジェネレータがDirectoryInfoSystem.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年に取得しています警告だ:私が必要)

をここで生成されたコードです。

私はthisthisを読んできましたが、それらはサービスレベルのカスタムネームスペースに関係しているようです。私は、CLRタイプとしてプロパティタイプを認識し、それ自身のDirectoryInfoクラスを生成しないようにジェネレータに指示する方法を知る必要があります。

+0

問題は、ISerializableフィールドをサポートしていませんDataContractSerializerを、使用しているという事実にあります。プリミティブと他のデータ変換のみ。代わりに、XmlSerializerを使用して、複雑さに対処するか、フィールドの型を文字列に変更する必要があります(これは意味がありますが、そうではありません)。 – jessehouwing

+0

@jessehouwing:私は 'XmlSerializerFormat'でより多くのログジャムを実行しました。その結果、文字列を使い、一方の端で解体し、もう一方の端で再構築しました。だから、私はWCFとSystem.IOの将来を考えています。なぜ私はそれをマークすることができる答えにしないでください? (ちなみに、お気に入りのスクラムフォーラムは何ですか?) – InteXX

答えて

1

クラスSystem.IO.DirectoryInfoは、DataContractSerializerではサポートされていません。代わりに、XmlSerializerを使用してみることもできますが、他の問題が発生する可能性があります。

単純な解決策は、正しいオブジェクトを再作成するのに必要なデータをキャプチャするstringプロパティを追加することです。元のプロパティーも保持することができます。[NonSerialized]属性でマークしてください。

また、OnSerializingおよびOnDeserializing属性を使用して、DirectoryInfo値が文字列フィールドに格納され、デシリアライズ後にDirectoryInfoが復元されるようにすることもできます。詳細については

は、以下を参照してください。

+0

ありがとう、ありがとう。これらのコールバックは面白いです。私はさらに調査します。 – InteXX

+1

具体的には、 'XmlSerializer'と' DirectoryInfo'にパラメータのないコンストラクタがないという問題がありました。あなたが参照しているブログ投稿は 'DirectoryInfo'が' DataContractSerializer'では動作するが、 'XmlSerializer'では動作しない理由を議論する素晴らしい仕事です。それは非常に良い記事です。 – InteXX

関連する問題