views:

431

answers:

1

Hi.

I have been struggling with this for a while and could really use some help.

I am attempting to design a WCF endpoint that allows for the streaming of images to the server and then returns imageURLs (i.e: "http://images.site.com/someimage.jpg").

Currently, the call to my WCF method looks like this:

for (var i = 0; i <= (Request.Files.Count - 1); i++)
{
client = new SOAPFileTransferServiceClient();
fileinfo = new FileTransferInfo();
m_objFile = Request.Files[i];

if (!(m_objFile == null | string.IsNullOrEmpty(m_objFile.FileName) |  _objFile.ContentLength < 1))
   {

   fileinfo.FileSize = m_objFile.ContentLength;
   fileinfo.FileName = Path.GetFileName(m_objFile.FileName);
   fileinfo.UserID = Context.Request["sid"].ToString();

   client.UploadFile(fileinfo, m_objFile.InputStream);

   if (retParam.param2 == 0)
   imgurl.Add(retParam.param1);

  }

}

The error I am struggling with is this:

Transfer mode Streamed is not supported by ReliableSessionBindingElement.

So far, I have tried creating a custom netTcp binding with added before the message encoding element. I have also changed my transerMode attribute to streamedRequest (thanks to a suggestion by marc_s) allowing for the request to be streamed but not the response. This seems like it would do the trick but I am still getting the same error (this time "Transfer mode StreamedRequest is not...").

I am out of ideas.

Below is the file transfer service contract. I have JSON and POX in addition to SOAP endpoints. I also have two MEX endpoints (one for mexHttp and the other for netTcp). Finally, I have both http (for json and pox) and netTcp (for soap) base addresses.

Does anything look wrong?

<service behaviorConfiguration="transferServiceBehavior" name="MyProject.API.FileTransfer.FileTransferService">
            <endpoint address="json" behaviorConfiguration="WebHttpEPBehavior"
              binding="webHttpBinding" bindingConfiguration="jsonWeb" name="MyJSONFileTransferEP"
              contract="MyProject.API.FileTransfer.IJSONFileTransferService" />
            <endpoint address="pox" behaviorConfiguration="WebHttpEPBehavior"
              binding="webHttpBinding" bindingConfiguration="poxWeb" name="MyPOXFileTransferEP"
              contract="MyProject.API.FileTransfer.IPOXFileTransferService" />
            <endpoint address="httpMex" binding="mexHttpBinding" bindingConfiguration=""
              contract="IMetadataExchange" />
            <endpoint address="soap" behaviorConfiguration="NetTcpEPBehavior"
              binding="customBinding" bindingConfiguration="netTcpCustom"
              name="MySOAPFileTransferEP" contract="MyProject.API.FileTransfer.ISOAPFileTransferService" />
            <endpoint address="nettcpMex" binding="netTcpBinding" bindingConfiguration=""
              contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:2544/filetransfer/" />
                <add baseAddress="net.tcp://localhost:2544/filetransfer/" />
              </baseAddresses>
            </host>
          </service>

And here is my custom binding used by the service contract:

<customBinding>
    <binding name="netTcpCustom"
             closeTimeout="00:01:00"
             openTimeout="00:01:00"
             receiveTimeout="00:10:00"
             sendTimeout="00:01:00">
      <reliableSession />
      <compositeDuplex />
      <oneWay />
      <windowsStreamSecurity protectionLevel="None" />
      <mtomMessageEncoding  />
      <tcpTransport maxBufferPoolSize="524288"
                    maxReceivedMessageSize="2147483647"
                    connectionBufferSize="8192"
                    hostNameComparisonMode="StrongWildcard"
                    channelInitializationTimeout="00:01:00"
                    maxBufferSize="2147483647"
                    maxPendingConnections="20"
                    maxOutputDelay="00:00:00.2000000"
                    maxPendingAccepts="5"
                    transferMode="StreamedRequest"
                    listenBacklog="20"
                    portSharingEnabled="false"
                    teredoEnabled="false">
        <connectionPoolSettings groupName="default" leaseTimeout="00:05:00"
            idleTimeout="00:02:00" maxOutboundConnectionsPerEndpoint="20" />
      </tcpTransport>
    </binding>
  </customBinding>

Finally, for what it is worth, below is my entire system.serviceModel definition in App.config:

<system.serviceModel>
    <client>
      <endpoint address="http://localhost:2542/auth/json" behaviorConfiguration="WebHttpEPBehavior"
        binding="webHttpBinding" bindingConfiguration="jsonWeb" contract="Trezoro.WebAPI.Authentication.IJSONAuthService"
        name="MyJSONAuthEP">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2542/auth/pox" behaviorConfiguration="WebHttpEPBehavior"
        binding="webHttpBinding" bindingConfiguration="poxWeb" contract="Trezoro.WebAPI.Authentication.IPOXAuthService"
        name="MyPOXAuthEP">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2542/auth/soap" behaviorConfiguration="BasicHttpEPBehavior"
        binding="basicHttpBinding" bindingConfiguration="soapWeb" contract="Trezoro.WebAPI.Authentication.ISOAPAuthService"
        name="MySOAPAuthEP">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2542/auth/mex" binding="mexHttpBinding"
        bindingConfiguration="" contract="IMetadataExchange" name="authmex">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2543/trade/json" behaviorConfiguration="WebHttpEPBehavior"
        binding="webHttpBinding" bindingConfiguration="jsonWeb" contract="Trezoro.WebAPI.Trade.IJSONTradeService"
        name="MyJSONTradeEP">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2543/trade/pox" behaviorConfiguration="WebHttpEPBehavior"
        binding="webHttpBinding" bindingConfiguration="poxWeb" contract="Trezoro.WebAPI.Trade.IPOXTradeService"
        name="MyPOXTradeEP">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2543/trade/soap" behaviorConfiguration="BasicHttpEPBehavior"
        binding="basicHttpBinding" bindingConfiguration="soapWeb" contract="Trezoro.WebAPI.Trade.ISOAPTradeService"
        name="MySOAPTradeEP">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2543/trade/mex" binding="mexHttpBinding"
        bindingConfiguration="" contract="IMetadataExchange" name="trademex">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2544/filetransfer/json" behaviorConfiguration="WebHttpEPBehavior"
        binding="webHttpBinding" bindingConfiguration="jsonWeb" contract="Trezoro.WebAPI.FileTransfer.IJSONFileTransferService"
        name="MyJSONFileTransferEP">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2544/filetransfer/pox" behaviorConfiguration="WebHttpEPBehavior"
        binding="webHttpBinding" bindingConfiguration="poxWeb" contract="Trezoro.WebAPI.FileTransfer.IPOXFileTransferService"
        name="MyPOXFileTransferEP">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:2545/filetransfer/soap" behaviorConfiguration="NetTcpEPBehavior"
        binding="customBinding" bindingConfiguration="netTcpCustom"
        contract="Trezoro.WebAPI.FileTransfer.ISOAPFileTransferService"
        name="MySOAPFileTransferEP">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
      <endpoint address="net.tcp://localhost:2545/filetransfer/nettcpMex"
        binding="netTcpBinding" bindingConfiguration="" contract="IMetadataExchange"
        name="filetransfermex">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
    </client>
    <bindings>
      <basicHttpBinding>
        <binding name="soapWeb" />
        <binding name="httpLargeMessageStream"
                 closeTimeout="00:01:00"
                 openTimeout="00:01:00"
                 receiveTimeout="00:10:00"
                 sendTimeout="00:01:00"
                 allowCookies="false"
                 bypassProxyOnLocal="false"
                 hostNameComparisonMode="StrongWildcard"
                 maxBufferSize="2147483647"
                 maxBufferPoolSize="2147483647"
                 maxReceivedMessageSize="2147483647"
                 messageEncoding="Text"
                 textEncoding="utf-8"
                 transferMode="StreamedRequest"
                 useDefaultWebProxy="true">
          <readerQuotas maxDepth="32"
                        maxStringContentLength="8192"
                        maxArrayLength="16384"
                        maxBytesPerRead="4096"
                        maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None"
                       proxyCredentialType="None"
                       realm="" />
            <message clientCredentialType="UserName"
                     algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
      <customBinding>
        <binding name="netTcpCustom"
                 closeTimeout="00:01:00"
                 openTimeout="00:01:00"
                 receiveTimeout="00:10:00"
                 sendTimeout="00:01:00">
          <reliableSession />
          <compositeDuplex />
          <oneWay />
          <windowsStreamSecurity protectionLevel="None" />
          <mtomMessageEncoding  />
          <tcpTransport maxBufferPoolSize="524288"
                        maxReceivedMessageSize="2147483647"
                        connectionBufferSize="8192"
                        hostNameComparisonMode="StrongWildcard"
                        channelInitializationTimeout="00:01:00"
                        maxBufferSize="2147483647"
                        maxPendingConnections="20"
                        maxOutputDelay="00:00:00.2000000"
                        maxPendingAccepts="5"
                        transferMode="StreamedRequest"
                        listenBacklog="20"
                        portSharingEnabled="false"
                        teredoEnabled="false">
            <connectionPoolSettings groupName="default" leaseTimeout="00:05:00"
                idleTimeout="00:02:00" maxOutboundConnectionsPerEndpoint="20" />
          </tcpTransport>
        </binding>
      </customBinding>
      <netTcpBinding>
        <binding name="netTcpWeb"
                 hostNameComparisonMode="StrongWildcard"
                 closeTimeout="00:01:00"
                 openTimeout="00:01:00"
                 receiveTimeout="00:10:00"
                 sendTimeout="00:01:00"
                 maxReceivedMessageSize="2147483647"
                 transferMode="StreamedRequest"
                 portSharingEnabled="false">
          <security mode="None" />
        </binding>
      </netTcpBinding>
      <webHttpBinding>
        <binding name="poxWeb"
                 maxBufferSize="1500000"
                 maxBufferPoolSize="1500000"
                 maxReceivedMessageSize="1500000">
          <readerQuotas maxDepth="32"
                        maxStringContentLength="656000"
                        maxArrayLength="656000"
                        maxBytesPerRead="656000"
                        maxNameTableCharCount="656000" />
        </binding>
        <binding name="jsonWeb"
                 maxBufferSize="1500000"
                 maxBufferPoolSize="1500000"
                 maxReceivedMessageSize="1500000">
          <readerQuotas maxDepth="32"
                        maxStringContentLength="656000"
                        maxArrayLength="656000"
                        maxBytesPerRead="656000"
                        maxNameTableCharCount="656000" />
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="Default" name="Trezoro.WebAPI.Authentication.AuthService">
        <endpoint address="json" behaviorConfiguration="WebHttpEPBehavior"
          binding="webHttpBinding" bindingConfiguration="jsonWeb" name="MyJSONAuthEP"
          contract="Trezoro.WebAPI.Authentication.IJSONAuthService" />
        <endpoint address="pox" behaviorConfiguration="WebHttpEPBehavior"
          binding="webHttpBinding" bindingConfiguration="poxWeb" name="MyPOXAuthEP"
          contract="Trezoro.WebAPI.Authentication.IPOXAuthService" />
        <endpoint address="soap" behaviorConfiguration="BasicHttpEPBehavior"
          binding="basicHttpBinding" bindingConfiguration="soapWeb" name="MySOAPAuthEP"
          contract="Trezoro.WebAPI.Authentication.ISOAPAuthService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:2542/auth/" />
          </baseAddresses>
        </host>
      </service>
      <service behaviorConfiguration="Default" name="Trezoro.WebAPI.Trade.TradeService">
        <endpoint address="json" behaviorConfiguration="WebHttpEPBehavior"
          binding="webHttpBinding" bindingConfiguration="jsonWeb" name="MyJSONTradeEP"
          contract="Trezoro.WebAPI.Trade.IJSONTradeService" />
        <endpoint address="pox" behaviorConfiguration="WebHttpEPBehavior"
          binding="webHttpBinding" bindingConfiguration="poxWeb" name="MyPOXTradeEP"
          contract="Trezoro.WebAPI.Trade.IPOXTradeService" />
        <endpoint address="soap" behaviorConfiguration="BasicHttpEPBehavior"
          binding="basicHttpBinding" bindingConfiguration="soapWeb" name="MySOAPTradeEP"
          contract="Trezoro.WebAPI.Trade.ISOAPTradeService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:2543/trade/" />
          </baseAddresses>
        </host>
      </service>
      <service behaviorConfiguration="transferServiceBehavior" name="Trezoro.WebAPI.FileTransfer.FileTransferService">
        <endpoint address="json" behaviorConfiguration="WebHttpEPBehavior"
          binding="webHttpBinding" bindingConfiguration="jsonWeb" name="MyJSONFileTransferEP"
          contract="Trezoro.WebAPI.FileTransfer.IJSONFileTransferService" />
        <endpoint address="pox" behaviorConfiguration="WebHttpEPBehavior"
          binding="webHttpBinding" bindingConfiguration="poxWeb" name="MyPOXFileTransferEP"
          contract="Trezoro.WebAPI.FileTransfer.IPOXFileTransferService" />
        <endpoint address="httpMex" binding="mexHttpBinding" bindingConfiguration=""
          contract="IMetadataExchange" />
        <endpoint address="soap" behaviorConfiguration="NetTcpEPBehavior"
          binding="customBinding" bindingConfiguration="netTcpCustom"
          name="MySOAPFileTransferEP" contract="Trezoro.WebAPI.FileTransfer.ISOAPFileTransferService" />
        <endpoint address="nettcpMex" binding="netTcpBinding" bindingConfiguration=""
          contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:2544/filetransfer/" />
            <add baseAddress="net.tcp://localhost:2544/filetransfer/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="WebHttpEPBehavior">
          <webHttp />
        </behavior>
        <behavior name="BasicHttpEPBehavior" />
        <behavior name="NetTcpEPBehavior" />
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="Default">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
        <behavior name="transferServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Any and all suggestions much appreciated. Thanks for your help.

A: 

Well, does the StreamedRequest method work if you drop the reliable session element? Could you live with that? If you're using netTcp, you're probably behind a corporate firewall, right? So you could possibly get away without the reliable session overhead....

Also - WCF has so many options and possible combinations of features - not everything makes sense, and not everything will work together - maybe this is just a limitation in WCF, not a configuration problem on your part.

The only odd thing about your config is the mtomMessageEncoding in your netTcp custom binding - why not use the much more efficient binary encoding??

<binding name="netTcpCustom"
         closeTimeout="00:01:00"
         openTimeout="00:01:00"
         receiveTimeout="00:10:00"
         sendTimeout="00:01:00">
  <reliableSession />
  <compositeDuplex />
  <oneWay />
  <windowsStreamSecurity protectionLevel="None" />
  <mtomMessageEncoding  />
  <tcpTransport maxBufferPoolSize="524288"

Why not use

  <binaryMessageEncoding />

instead??

marc_s
Marc - do you know if it is possible to stream images to a server and then get a string collection as a response in WCF? I mean, just from a "what is doable" standpoint - are you aware that this is possible?
Code Sherpa
Yes, of course this is possible. However: once call would most likely stream exactly one image up to the server, and return exactly one URL back.
marc_s
Wow - this was so less complicated than I was making it. I finally figured out how to do what I wanted and it was simply by creating a string collection that adds each url string returned by the WCF upload method called from the client. I did, however, learn that transferMode = streamed and the composite duplex attribute don't play well together. None-the-less, thanks a ton for your help.
Code Sherpa