2011-05-23 78 views
4

我有一個WCF服務暴露一個合同與操作:WCF服務生成的代理類暴露功能的ByRef子

<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> 

我的問題是通過將服務引用到客戶端,在生成子(void函數)生成的代理類,而不是功能我期待。

更重要的是,生成的子程序不接受我的消息契約作爲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轉換到我的內存中小號tream。

這在某些方面類似於other posts,但您可以看到,我的合同中沒有涉及枚舉 - 存在的枚舉會導致奇怪的代理類生成被標記爲類似帖子中的答案。

我在哪裏配置代理行爲以使用我指定的合約?很明顯,我目前在開發/測試環境中,但是當這最終進入生產時,它將傳遞給服務的內存和文件流,並且返回的流可以是任何格式,說實話,我打算把它當作抽象流類。我現在可以看到的唯一方法就是改變我的流中與預期的相同的流流,但是肯定有更好的方法嗎?

回答

3

總白癡。我沒有在服務參考配置中檢查「始終生成消息合同」中的框。

一旦檢查我的代理類簽名已更改爲我的OP中的預期簽名。

道歉轂小傢伙^^

+0

我要等2天就能記住我自己的答案*將*答案,所以免費10分給誰就給誰希望把一個類似的答案在這裏說例如「您是否檢查過您的扳手,始終生成郵件聯繫人」框?「所以我可以在這裏關閉一些東西。 =) – Smudge202 2011-05-23 11:43:59

+0

雖然......最好知道是否有可能在合同上聲明哪些操作是我希望我的客戶端生成消息合約的,而哪些合同我不這樣做。例如,在上面的實現中,如果我添加了用於測試的基本Echo函數,那麼現在必須使用「EchoRequest」對象而不是基本字符串來調用該函數,並且類似地從EchoResponse回退。 – Smudge202 2011-05-23 11:46:34

+0

對於Echo函數,我只需創建一個單獨的接口並使服務代碼實現兩個接口。這樣每個合同的定義和配置可以單獨完成,您可以使用Echo方法的ServiceContract模式。至於客戶端消息合約,如果您自定義爲服務生成WSDL,那麼您可以決定要向客戶端展示的內容。 – 2011-05-23 12:44:04