WCF defaults to buffering the entire message before transmitting. It is possible to stream your data so data can start to be processed on the server or client before it entirely transmitted.
Comprehensive documentation can be found on
Set server app.config to be:
<bindings> <netTcpBinding> <binding name="customNetTcpBinding" maxBufferSize="200000000" maxReceivedMessageSize="200000000" transferMode="Streamed"> </binding> </netTcpBinding> </bindings>
The above should allow files of up to about 190mb to be streamed.
The key attribute is:
transferMode="Streamed" - default is buffered
The client config required is.
<bindings> <netTcpBinding> <binding name="NetTcpBinding_IFileUpload" transferMode="Streamed" /> </netTcpBinding> </bindings>
For a complete example, our response type definition:
public class UploadFileResponse { public string Message { get; set; } }
Service interface:
[ServiceContract] public interface IFileUpload { [OperationContract] UploadFileResponse UploadFileViaStream(Stream fileStream); }
Service class implementation:
public class FileUploadService : IFileUpload { public UploadFileResponse UploadFileViaStream(Stream stream) { var response = new UploadFileResponse(); using (var fileStream = File.Create("teststream")) { stream.CopyTo(fileStream); } response.Message = "Successfully completed"; return response; } }
And if we look at Microsoft Service Trace Viewer we can see that it is indeed streaming our data:
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent"> <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system"> <EventID>0</EventID> <Type>3</Type> <SubType Name="Information">0</SubType> <Level>8</Level> <TimeCreated SystemTime="2014-03-06T18:17:25.8188503Z" /> <Source Name="System.ServiceModel.MessageLogging" /> <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" /> <Execution ProcessName="WCFLargeFileAPI.vshost" ProcessID="2984" ThreadID="11" /> <Channel /> </System> <ApplicationData> <TraceData> <DataItem> <MessageLogTraceRecord Time="2014-03-06T18:17:25.8188503+00:00" Source="ServiceLevelReceiveRequest" Type="System.ServiceModel.Channels.StreamedMessage" xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace"> <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> <s:Header> <a:Action s:mustUnderstand="1">http://tempuri.org/IFileUpload/UploadFileViaStream</a:Action> <a:MessageID>urn:uuid:7e9efd61-3868-481c-ab5d-17c19f93526a</a:MessageID> <a:ReplyTo> <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> </a:ReplyTo> <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink"<uIDPo1d4u3tgmU9MjjApxUoHeD8AAAAABU27dsajsEGNM7x3QCkSz7rxDZ3MpsRFrpqvfafNFOAACQAA</VsDebuggerCausalityData> <a:To s:mustUnderstand="1">net.tcp://localhost:7891/<a:To> </s:Header> <s:Body>... stream ...</s:Body> </s:Envelope> </MessageLogTraceRecord> </DataItem> </TraceData> </ApplicationData> </E2ETraceEvent>