好的,这在VS 2013中运行得很好。只有在我升级到2015年之后我才开始重新开始工作,问题就出现了。
简而言之,我不确定如何告诉WCF代理生成器为属性类型指定CLR命名空间;显然现在需要这样做。
这是我的合同:
<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中收到的警告:
自定义工具警告:无法导入wsdl:portType 详细信息:运行WSDL导入扩展时抛出异常:System.ServiceModel.Description.DataContractSerializerMessageContractImporter 错误:无法导入名称空间“http://schemas.datacontract.org/2004/07/System.IO”中具有数据协定名称“DirectoryInfo”的ISerializable类型。无法为ISerializable类型自定义数据协定命名空间,并且生成的命名空间“QbServer”与所需的CLR命名空间“System.IO”不匹配。检查所需的命名空间是否已映射到其他数据协定命名空间,并考虑使用命名空间集合显式映射它。 XPath到错误源:// 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
类。
答案 0 :(得分:2)
DataContractSerializer不支持类System.IO.DirectoryInfo
。相反,您可以尝试使用XmlSerializer,但您可能会遇到其他问题。
一个简单的解决方案是添加string
属性,该属性捕获重新创建正确对象所需的数据。您也可以保留原始属性,只需确保使用[NonSerialized]
属性进行标记。
或者,您可以使用OnSerializing
和OnDeserializing
属性来确保DirectoryInfo值存储在字符串字段中,以便在反序列化后还原DirectoryInfo。
有关详细信息,请参阅: