Asp.net 在WCF中实例化类
我正在编写一个WCF WebMethod来将文件上传到其中,我从web上获取了其中的片段。WCF界面如下所示:Asp.net 在WCF中实例化类,asp.net,vb.net,wcf,webmethod,Asp.net,Vb.net,Wcf,Webmethod,我正在编写一个WCF WebMethod来将文件上传到其中,我从web上获取了其中的片段。WCF界面如下所示: <ServiceContract()> Public Interface ITransferService <OperationContract()> Sub UploadFile(ByVal request As RemoteFileInfo) End Interface <MessageContract()> Public
<ServiceContract()>
Public Interface ITransferService
<OperationContract()>
Sub UploadFile(ByVal request As RemoteFileInfo)
End Interface
<MessageContract()>
Public Class RemoteFileInfo
Implements IDisposable
<MessageHeader(MustUnderstand:=True)>
Public FileName As String
<MessageHeader(MustUnderstand:=True)>
Public Length As Long
<MessageBodyMember(Order:=1)>
Public FileByteStream As System.IO.Stream
Public Sub Dispose() Implements IDisposable.Dispose
If FileByteStream IsNot Nothing Then
FileByteStream.Close()
FileByteStream = Nothing
End If
End Sub
End Class
有谁能告诉我们为什么不能使用以下方法创建TransferService
的实例:
Dim cu As New ServiceReference1.TransferServiceClient()
如果我尝试上面的方法,它会打断这条线:
cu.UploadFile(uri)
…和UploadFile必须使用三个参数(FileName、Length、FileByteStream)调用,即使没有使用此签名的方法
为什么在创建此类实例时需要该接口?当您使用“添加服务引用”对话框为您的服务创建代理时,默认情况下,代理创建代码将“展开”消息契约,就像您拥有的一样。如果希望消息契约按照您在代理服务器端的定义显示,则需要选择“高级”选项卡,并选中“始终生成消息契约”选项。这样,您也可以在客户端中获得消息契约。问题是,当遇到作为参数的
MessageContract
时,WCF客户端生成默认假定您想要实现消息样式接口,并将消息契约中的离散属性作为客户端接口的一部分提供
MSDN中的这篇文章非常详细地描述了如何使用消息传递合同,我怀疑微软之所以选择这种默认行为,是因为你可以玩一些消息“游戏”
然而,如果您在客户端检查为您的上传文件生成的代码,有一些有趣的花絮可以帮助解释发生了什么
第一个是界面中UploadFile方法的注释:
'CODEGEN: Generating message contract since the operation UploadFile is neither RPC nor document wrapped.
...
Function UploadFile(ByVal request As ServiceReference1.RemoteFileInfo) As ServiceReference1.UploadFileResponse
这意味着,如果消息契约具有不同的实现,那么契约的生成方式也会有所不同
第二,您将看到,用于实际进行服务调用的代码没有什么特殊之处:
Public Sub UploadFile(ByVal FileName As String, ByVal Length As Long, ByVal FileByteStream As System.IO.Stream)
Dim inValue As ServiceReference1.RemoteFileInfo = New ServiceReference1.RemoteFileInfo()
inValue.FileName = FileName
inValue.Length = Length
inValue.FileByteStream = FileByteStream
Dim retVal As ServiceReference1.UploadFileResponse = CType(Me,ServiceReference1.ITransferService).UploadFile(inValue)
End Sub
因此,在本例中,您的代码所做的正是生成的代码所做的。然而,如果MessageContract更复杂,我怀疑情况将不再如此
那么,对于你的问题:
有人能告诉我为什么不可能创建
TransferService使用以下方法
只要验证方法调用的实现功能等同于代码,就没有理由不采用这种方法
有两个选项可用于更改客户端中方法的默认生成:
1) 从RemoteFileInfo
类中删除MessageContract
属性
2) 虽然这似乎有点违反直觉,但您可以选中。Wow-惊人的答案-谢谢!关于您的评论:>>从RemoteFileInfo类Re RemoteFileInfo中删除MessageContract属性:是的,使用DataContract是一种最佳做法,尽管这不是严格要求的,因为WCF将自动处理普通的旧类对象(POCO)。重新游戏:我主要指的是可以操作底层SOAP消息的大量方法(加密部分、使用不同的名称空间、使用不同的序列化引擎等),这些方法可能会影响客户机生成的代码,也可能不会影响客户机生成的代码(有关各种功能的深入讨论,请参阅MSDN文章)。超级。非常感谢您的详细回复。只需阅读一本关于WCF 4的书。要补充您的答案,DataContract不能用于任何类型的流对象,MessageContract必须用于流。
Public Sub UploadFile(ByVal FileName As String, ByVal Length As Long, ByVal FileByteStream As System.IO.Stream)
Dim inValue As ServiceReference1.RemoteFileInfo = New ServiceReference1.RemoteFileInfo()
inValue.FileName = FileName
inValue.Length = Length
inValue.FileByteStream = FileByteStream
Dim retVal As ServiceReference1.UploadFileResponse = CType(Me,ServiceReference1.ITransferService).UploadFile(inValue)
End Sub