【发布时间】:2016-04-01 04:17:33
【问题描述】:
好的,这在 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 类。
【问题讨论】:
-
问题在于您使用的是DataContractSerializer,它不支持ISerializable 字段。只有原语和其他数据契约。您将需要改用 XmlSerializer 并处理增加的复杂性,或者将字段的类型改为字符串(这很有意义,不是吗)。
-
@jessehouwing:我在使用
XmlSerializerFormat时遇到了更多的问题,所以我最终只使用了一个字符串,一端解构,另一端重构。所以感谢您的参与——我将来会警惕 WCF 和System.IO。为什么不把它作为一个答案,以便我可以标记它? (顺便说一句,你最喜欢的 Scrum 论坛是什么?)
标签: wcf visual-studio-2013 visual-studio-2015