Search code examples
c#wcfwcf-rest

WCF Restful Service - Send File with Multiple fields in one requert


I am in the process of developing a WCF Restful Service. One of the requirements of the WCF is to allow a client to upload an image file and several input parameters that may contain multiple values.

I thought of several ways of sending a file with input parameters in one request. I am not sure what the best approach would be.

1) Accept a stream that contains a multipart form-data stream. A huge disadvantage with this approach is that I have to write a multipart parser. (aspNetCompatibilityEnabled="false")

[WebInvoke (UriTemplate = "Account",Method = "POST")]
public String Account(System.IO.Stream stream) {
MultiPartParser(stream);
}

2) Send the file as a stream and send other data in the QueryString. Only issue with this approach is that the values may be multi-line text data.

[WebInvoke (UriTemplate = "Account?input1={val1}&input2={val2}",Method = "POST")]
public String Account(System.IO.Stream stream) {

}

3) Convert the file as a Base64 string and encapsulate it in JSON or XML and send it with the other input parameters. Are there any limitations of this approach?

[WebInvoke (UriTemplate = "Account",Method = "POST")]
public String Account(String ImageFile, String input1, String input2) {

}

What is the best approach? Thank you for your time.


Solution

  • As always, the asnwer is "it depends". You mentioned the pros/cons of each approach, so it will really depend on your situation.

    1. Pro: the file contents are not encoded (i.e., no size bloat). Con: you need to write the multipart parser on the server (and to package the request on the client), the multipart headers will add some (often non-significant) overhead to the requests

    2. Pro: simple, operation is easy to write. Con: may need to URL-encode chars such as new line; size limitation of URIs may be an issue if additional data is large

    3. Pro: No need for encoding, operation is easy to write. Con: size bloat due to base64-encoding (you can declare the parameter as byte[] so the decoding is done automatically for you), client will need to encode the file content, as well as wrap all the parameters from the request.

    There's also a fourth option, which is to pass the additional parameters as HTTP headers.

    1. Pro: no size limitation as in the URIs. Con: parameters are not explicitly declared, need to fetch them from the headers using the WebOperationContext, and still need to URI-encode chars outside the 0x20-0x7E range