Asp.net 在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

我正在编写一个WCF WebMethod来将文件上传到其中,我从web上获取了其中的片段。WCF界面如下所示:

<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