1

I have an application that submits a large amount of data to a WCF web service. Since the data can be large I wanted to use the Streamed TransportMode so I can process the data as its coming in instead of buffering it all.

When Im debugging the application, the streaming works as expected. Once I actually publish the service to my IIS server, the streaming no longer works and the data seems to just be getting buffered.

I tested it by putting a throw new Exception at the beginning of the web service function and changed the source stream to provide "infinite data".

Here is the Server source code:

[ServiceContract]
public class Service1
{
    [OperationContract]
    public void SubmitData(Stream stream)
    {
        throw new Exception("Test");
        using (var reader = new StreamReader(stream))
        {
            string line = reader.ReadLine();
            // Do Something...
        }
    }
}

Here is the client code:

Service1Client client = new Service1Client();
client.Endpoint.Address = new EndpointAddress(address);
client.Open();
using (var stream = new InfiniteDataStream())
    client.SubmitData(stream);
client.Close();  

.

class InifiteDataStream : Stream
{
    ...

    public override int Read(byte[] buffer, offset, count)
    {
        // Create random data...
        return count;
    }

    ...
}

Server Web.Config:

  <system.serviceModel>
    <bindings>
      <basicHttpsBinding>
        <binding transferMode="Streamed" maxReceivedMessageSize="2147483647">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName" />
          </security>
      </basicHttpsBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
  </system.serviceModel>

Client App.Config:

<system.serviceModel>
<bindings>
  <basicHttpsBinding>
    <binding name="BasicHttpsBinding_Service1" transferMode="Streamed" >
      <security mode="TransportWithMessageCredential" />
    </binding>
  </basicHttpsBinding>
</bindings>
<client>
  <endpoint address="https://localhost:56297/WebService/Service1.svc"
    binding="basicHttpsBinding" bindingConfiguration="BasicHttpsBinding_Service1"
    contract="WebService.Service1" name="BasicHttpsBinding_Service1" />
</client>

Like I said this code works exactly how it should when Im debugging in VS (w/ IIS Express), when I run the client it gives the exception instantly. When I run the client pointed to the web server it just sits there, until it eventually gets a receive timeout exception. Which would be expected from a buffered transport since it will never be done buffering. And if I debug the client application while its pointed at the web server, I can see that the Read function is being called in the stream.

Is there some kind of configuration in IIS that needs to be changed? I looked through the settings and didn't see anything apparent.

Update: I found this Microsoft forums thread post https://social.msdn.microsoft.com/Forums/vstudio/en-US/cfe625b2-1890-471b-a4bd-94373daedd39/streamedrequest-possible-under-iis?forum=wcf
The last comment indicates this was a bug that was fixed in .Net 4.5 but Im builiding with 4.6.1

Also, my server is running IIS 8.5 so I decided to try the same test on my local Win10 machine which has IIS 10, still doing the same thing.

Using Wireshark I was able to confirm that the data is being streamed to the server, its just not getting processed by the server. I also tried changing transferMode="Streamed" to transferMode="StreamedRequest", no luck.

Brian Tacker
  • 1,091
  • 2
  • 18
  • 37
  • Duplicate? Have you read http://stackoverflow.com/questions/10225229/getting-streaming-in-iis-hosted-wcf-service-to-work?rq=1 – tgolisch Apr 10 '17 at 20:40
  • Yes I stumbled on that at one point, the accepted answer references the same MSDN thread post that I referenced in my update. Stating that the issue is fixed in .Net 4.5 – Brian Tacker Apr 11 '17 at 03:16
  • Just to see if the issue has something to do to the SSL/HTTPs. Have you tried by any chance to use non-secured binding instead? – Eugene Komisarenko Apr 12 '17 at 17:48
  • @EugeneKomisarenko Yes I attempted to change from basicHttpsBinding to basicHttpBinding and removed the tags from the bindings, same result – Brian Tacker Apr 12 '17 at 17:54
  • Before making further changes then I would really recommend enabling WCF diagnostics then https://weblogs.asp.net/seaniannuzzi/wcf-diagnostics-implementation-in-5-easy-steps and see if you can detect the issue from those logs first. – Eugene Komisarenko Apr 12 '17 at 17:55
  • Here you go: https://drive.google.com/file/d/0B_2_5gyfCSfHQnptZ1BUdjBjeG8/view?usp=sharing – Brian Tacker Apr 12 '17 at 19:51
  • Brian, I have deployed your service to IIS 8.0 and got it working as is. The data is streaming until the exception is thrown and fault propagated back to client with "Test" message in it. The only change I made was adding diagnostics. Please do the same and share your .svclog files to compare. Forgot to mention app pool is running under LocalService in Integrated managed pipeline mode with 4.0.30319 framework. – Eugene Komisarenko Apr 13 '17 at 13:04
  • You say its streaming the data until it throws the exception, but the exception should be thrown almost instantly. In the custom stream I put in a condition to return 0 on the 1000th read, which it shouldnt reach since the exception should be thrown way before that, is that condition being reached for you? – Brian Tacker Apr 13 '17 at 14:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/141657/discussion-between-eugene-komisarenko-and-brian-tacker). – Eugene Komisarenko Apr 13 '17 at 14:39

1 Answers1

1

Replacing of the throw new Exception line of code with the writing to the log file demonstrated that there is nothing inherently wrong with the code and streaming of the request from client to server is working as expected under service instance hosted in the locally running IIS.

Eugene Komisarenko
  • 1,533
  • 11
  • 25
  • Correct me if Im wrong but wont this only affect the Response? Im attempting to Stream the Request. – Brian Tacker Apr 12 '17 at 18:03
  • You were right, the previous version of the answer was talking about the streaming of the response, see updated answer about the side effects of the throw Exception. – Eugene Komisarenko Apr 13 '17 at 16:48
  • Thank you for your finding, there must have been a different issue with my original test code which was to write the stream to a file, it was not writing the file until the stream was completely sent. So I guess I introduce a new issue with the exception test. But whatever the original issue was Im not sure because now its working correctly. – Brian Tacker Apr 13 '17 at 17:02