WCF streaming issue with ASP.NET

I have a WCF service hosted in an ASP.NET application and am trying to download a file from another ASP.NET client application using streaming mode. I keep getting the following error:

The remote server returned an unexpected response: (400) Bad Request.

I scanned the network for help, but to no avail.

Host configuration:

<bindings> <basicHttpBinding> <binding name="FileTransferServicesBinding" transferMode="Streamed" messageEncoding="Mtom" sendTimeout="01:05:00" maxReceivedMessageSize="10067108864"> </binding> </basicHttpBinding> </bindings> <services> <service behaviorConfiguration="FileTransferServiceBehavior" name="WebServiceHost.TransferService"> <clear /> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="FileTransferServicesBinding" contract="WebServiceHost.ITransferService"> <identity> <dns value="localhost"/> <certificateReference storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectDistinguishedName" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"> </endpoint> <host> <baseAddresses> <add baseAddress="http://localhost:11291/TransferService.svc" /> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior name="FileTransferServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> 

Contract Code:

 [ServiceContract] public interface ITransferService { [OperationContract] RemoteFileInfo DownloadFile(DownloadRequest request); [OperationContract] void UploadFile(RemoteFileInfo request); [OperationContract] string TestMethod(); } [MessageContract] public class DownloadRequest { [MessageBodyMember] public string FileName; } [MessageContract] public class RemoteFileInfo : IDisposable { [MessageHeader(MustUnderstand = true)] public string FileName; [MessageHeader(MustUnderstand = true)] public long Length; [MessageBodyMember(Order = 1)] public System.IO.Stream FileByteStream; public void Dispose() { if (FileByteStream != null) { FileByteStream.Close(); FileByteStream = null; } } } 

Client Configuration:

 <bindings> <basicHttpBinding> <binding name="FileTransferServicesBinding" sendTimeout="01:05:00" maxReceivedMessageSize="10067108864" messageEncoding="Mtom" transferMode="Streamed" /> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:11291/TransferService.svc/" binding="basicHttpBinding" bindingConfiguration="FileTransferServicesBinding" contract="TransferServiceReference.ITransferService" name="FileTransferService" kind=""> <identity> <dns value="localhost" /> <certificateReference storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectDistinguishedName" /> </identity> </endpoint> </client> <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> 

Client Code:

 ITransferService clientUpload = new TransferServiceClient(); string datetime = clientUpload.TestMethod(); var uploadRequestInfo = new RemoteFileInfo(); uploadRequestInfo.FileName = FileUpload1.FileName; uploadRequestInfo.Length = FileUpload1.PostedFile.ContentLength; uploadRequestInfo.FileByteStream = FileUpload1.PostedFile.InputStream; clientUpload.UploadFile(uploadRequestInfo); 

The call is not made for clientUpload.TestMethod () and clientUpload.UploadFile (uploadRequestInfo). In buffered mode, clientUpload.TestMethod () is called, so the problem is with the configuration in streaming mode.

I would be grateful for any help on this. Thanks.

+4
source share
2 answers

I have the same problems and I found this article in the explanation to solve your error. http://www.c-sharpcorner.com/uploadfile/BruceZhang/stream-operation-in-wcf/ .

Hope this help!

+2
source

The problem is your data contract - public System.IO.Stream FileByteStream; . Remove this member from the data contract and use stream in your work contract - for example:

 [OperationContract(OneWay=true)] void UploadFile(RemoteFileInfo request, System.IO.Stream fileData); 

Quote from Big Data and Streaming (MSDN):

You should not use the resulting System.IO.Stream types inside data contracts. Stream data should be streamed using the streaming model explained below under the Streaming Data section.

The Streaming Data section of the same link explains this in detail.

The problem is your data contract - public System.IO.Stream FileByteStream; . Remove this member from the data contract and use stream in your work contract - for example:

 [OperationContract(OneWay=true)] void UploadFile(RemoteFileInfo request, System.IO.Stream fileData); 

Quote from Big Data and Streaming (MSDN):

You should not use the resulting System.IO.Stream types inside data contracts. Stream data should be streamed using the streaming model explained below under the Streaming Data section.

The Streaming Data section of the same link explains this in detail.

EDIT: Apologies - I missed the limits. You have two ways to solve the problem: use MessageContract or use several operations for one transaction. An example of using multiple operations will be

 [OperationContract] Token UploadFile(System.IO.Stream fileData); [OperationContract] void ProvideFileInfo(Token token, RemoteFileInfo request); 

First, upload the data to the server, and the server issues a token (for example, guid), use the token to update other information.

A more preferable way would be to use MessageContract and which you have already tried. Some suggestions for troubleshooting:

  • If your hosting is in IIS, check maxRequestLength in web.config. Try uploading small files.
  • Instead of directly using the FromFile stream, store it on disk and use the stream on top of it. The reasoning behind the HTTP request stream can be cleared at boot time.
  • Use a tool, such as a violinist, and see the message passing through the wire to the service, which may give the key.
+2
source

All Articles