【问题标题】:WCF Service Generated Proxy Class Exposing Function as ByRef SubWCF 服务生成的代理类将函数公开为 ByRef Sub
【发布时间】:2011-08-31 00:54:15
【问题描述】:

我有一个 WCF 服务公开一个合同和操作:

<ServiceContract(Namespace:="ImageSystem")> _
Public Interface IUploadService

    <OperationContract()> _
    Function UploadFile(ByVal file As ImageUpload) As ImageUpload

End Interface

该函数接收并返回一个“ImageUpload”,其定义如下:

<MessageContract()> _
Public Class ImageUpload

    <MessageHeader()> _
    Public Property ImageID() As Nullable(Of Long)

    <MessageHeader()> _
    Public Property ImageTypeID() As Long

    <MessageHeader()> _
    Public Property IncludeInGallery() As Boolean

    <MessageHeader()> _
    Public Property OriginalFileName() As String

    <MessageHeader()> _
    Public Property ErrorDescription() As String

    <MessageBodyMember()> _
    Public Data As System.IO.Stream

End Class

端点定义如下(不确定这是否重要,但以防万一):

客户:

<configuration>
  <system.serviceModel>

    <bindings>
      <netTcpBinding>
        <binding name="netTcpStreamBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
          receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
          transferMode="Streamed" transactionProtocol="OleTransactions"
          hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
          maxBufferSize="20971520" maxConnections="10" maxReceivedMessageSize="20971520">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None" />
        </binding>
    </bindings>

    <client>
      <endpoint address="net.tcp://localhost:809/UploadService" binding="netTcpBinding"
        bindingConfiguration="netTcpStreamBinding" contract="UploadService.Local.IUploadService"
        name="NetTcpBinding_IUploadService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>

  </system.serviceModel>

</configuration>

服务器:

<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="netTcpStreamBinding" transferMode="StreamedRequest" maxBufferSize="20971520"
                 maxReceivedMessageSize="20971520" >
          <security mode="None"/>
        </binding>
      </netTcpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="UploadServiceBehaviour"
               name="ImageSystem.SVC.UploadService">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="netTcpStreamBinding"
          contract="ImageSystem.SVC.IUploadService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:809/UploadService" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="UploadServiceBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the 
          metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="false"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  
          Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

我的问题是通过向客户端添加服务引用生成的代理类正在生成一个子(无效函数)而不是我期望的函数。

更重要的是,生成的 sub 不接受我的消息合约作为 in/out 参数,而是列出消息合约的成员。

也就是说,我希望自动生成的代理类具有以下签名:

Public Function UploadFile(ByVal file As ImageUpload) As ImageUpload

相反,它正在生成:

    Public Sub UploadFile(ByRef ErrorDescription As String, ByRef ImageID As System.Nullable(Of Long), ByRef ImageTypeID As Long, ByRef IncludeInGallery As Boolean, ByRef OriginalFileName As String, ByRef Data As System.IO.Stream)
        Dim inValue As UploadService.Local.ImageUpload = New UploadService.Local.ImageUpload()
        inValue.ErrorDescription = ErrorDescription
        inValue.ImageID = ImageID
        inValue.ImageTypeID = ImageTypeID
        inValue.IncludeInGallery = IncludeInGallery
        inValue.OriginalFileName = OriginalFileName
        inValue.Data = Data
        Dim retVal As UploadService.Local.ImageUpload = CType(Me,UploadService.Local.IUploadService).UploadFile(inValue)
        ErrorDescription = retVal.ErrorDescription
        ImageID = retVal.ImageID
        ImageTypeID = retVal.ImageTypeID
        IncludeInGallery = retVal.IncludeInGallery
        OriginalFileName = retVal.OriginalFileName
        Data = retVal.Data
    End Sub

这随后会导致流转换问题,因为生成的函数允许我将内存流作为输入传递(当传递给服务时它可以正常工作),而不是向我传回新的响应流,它尝试将从服务接收到的 MessageBodyStream 转换为我的内存流。

这在某些方面类似于other posts,但正如您所见,我的合同中没有涉及枚举 - 枚举的存在导致奇怪的代理类生成被标记为类似帖子中的答案。

我是否在任何地方配置代理行为以使用我指定的合同?显然我目前处于开发/测试环境中,但是当最终投入生产时,它将是传递给服务的内存和文件流,并且返回的流可以是任何格式,老实说,我打算将其视为抽象流类。我现在能看到的唯一解决方法是将我的 in 流更改为与预期的 out 流相同,但肯定有更好的方法吗?

【问题讨论】:

    标签: vb.net wcf wcf-client


    【解决方案1】:

    彻头彻尾的白痴。我没有选中服务参考配置中“始终生成消息合同”的复选框。

    检查后,我的代理类签名已更改为我的 OP 中的预期签名。

    向小白道歉^^

    【讨论】:

    • 我必须等待 2 天才能将我自己的答案标记为 答案,因此,如果您想在这里提出类似的答案,可以免费获得 10 分“您是否选中了扳手的‘始终生成消息联系人’框?”所以我可以在这里关闭一些。 =)
    • 虽然......最好知道是否可以在某处声明我希望我的客户为其生成消息合同的合同上的哪些操作,而我不可以。例如,在上面的实现中,如果我添加了基本的 Echo 函数进行测试,我现在必须使用“EchoRequest”对象而不是基本字符串来调用该函数,并且类似地从 EchoResponse 中回滚。
    • 对于 Echo 功能,我只需创建一个单独的接口并让服务代码实现这两个接口。这样每个合约的定义和配置都可以单独完成,您可以将 ServiceContract 模式用于 Echo 方法。至于客户端消息契约,如果您为服务自定义生成 WSDL,那么您可以决定要向客户端公开什么。
    • 好点,再次感谢您的帮助(我相信您过去曾帮助我处理其他事情)。随意将其放入答案中,我会标记它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多