16

I am looking into using WCF for a project which would require the ability for people to upload large files (64MB-1GB) to my server. How would I handle this with WCF, possibly with the ability to resume uploads.

In order to handle a larger client base, I wanted to test out JSON via WCF. How would this affect the file upload? Can it be done from JSON, or would they need to switch to REST for the upload portion?

esac
  • 24,099
  • 38
  • 122
  • 179

3 Answers3

19

If you want to upload large files, you'll definitely need to look into WCF Streaming Mode.

Basically, you can change the transfer mode on your binding; by default, it's buffered, i.e. the whole message needs to be buffered on the sender, serialized, and then transmitted as a whole.

With Streaming, you can define either one-way streaming (for uploads only, for downloads only) or bidirectional streaming. This is done by setting the transferMode of your binding to StreamedRequest, StreamedResponse, or just plain Streamed.

<bindings>
   <basicHttpBinding>
      <binding name="HttpStreaming" 
               maxReceivedMessageSize="2000000"
               transferMode="StreamedRequest"/>
   </basicHttpBinding>
</bindings>

Then you need to have a service contract which either receives a parameter of type Stream (for uploads), or returns a value of type Stream (for downloads).

[ServiceContract]
public interface IFileUpload
{
    [OperationContract]
    bool UploadFile(Stream stream);
}

That should do it!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • What if your request/response must follow a specific schema? Ie, wat if the request must be a specific object, and your wsdl needs to reflect that? How would you enforce that with a stream? – Jeremy Mar 05 '13 at 20:35
  • @Jeremy: as my response says: if you want to use streamed transfer, you can **only** use a single parameter of type `Stream` (or a return value of type `Stream`). If you cannot design your service like this and must follow other specific requirements, then you just cannot use streaming transfer, unfortunately. There's no *magic* way to make this work. – marc_s Mar 05 '13 at 20:47
  • @marc_s how about a single large string parameter ? [My recent question](https://stackoverflow.com/questions/48774474/parameter-size-limit-for-strings#comment84577011_48774474) was marked as duplicate of this but i can with setting the proper parameter pass easily 1.2gb `byte[]` parameter to method without issue but if you change the parameter type from `byte[]` to `string` then it limits to about 28 mb. I must have `string` as a parameter. – Franck Feb 14 '18 at 13:17
  • @marc_s: from MSDN: **At least one of the types of the parameter and return value must be either Stream** from article: [How to: Enable Streaming](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-enable-streaming) I don't think having a parameter of the string type is required and we can have other input parameters. Is this the other way around? – Arian Jan 18 '19 at 21:07
1

MTOM is optimized to handle large binary data.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 1
    MTOM alone doesn't really help much - you still need to assemble the whole message in a buffer to transmit. – marc_s Dec 20 '09 at 12:30
0

You can use webHttpBinding with TransferMode streamed and a single Stream parameter or Stream response (as appropriate) for large file up/downloads, but you'd have to send any request metadata via URLs and/or headers, unless you're going to devise your own framing on the Stream. You'll have to build a custom non-HTML client (like Silverlight, Flash, etc) though, since browsers don't support random access to local files, and the normal file upload will be a form post, not JSON.

nitzmahone
  • 13,720
  • 2
  • 36
  • 39