Uploading a file to ServiceStack from Angular JS

Hi there,

We’re trying to upload a file and post some JSON data in a DTO to a ServiceStack endpoint from Angular JS. The endpoint does work and we can upload files to it using C#, but for some reason this does not seem to be as easy from Angular JS.

Are there any tricks we should know about? On the .NET side, the SS endpoint simply reads from the Request.Files collection. In JS, should we be:

  1. Using FileReader to readAsBinaryString and then send that to the endpoint.
  2. Using FileReader to readAsArrayBuffer then convert the byte array into a binary string and then send that to the endpoint.
  3. Using FileReader to readAsDataURL into Base64 and then convert the Base64 into a binary string and then send that to the endpoint.
  4. Doing something completely different?

Any help would be very much appreciated.

Kind regards,
Annie Luxton

Hi Annie,

ServiceStack just processes standard HTTP File Uploads, i.e. as sent using HTML’s native multipart/form-data FORMs which will then be accessible in ASP.NET’s Request.Files collection so you should look at using a solution that simulates that, e.g. You can use Fine Uploader component to easily upload multiple files.

I haven’t tried it, but googling around I’ve found this article showing how to upload multiple files using the fetch API.

Thanks Demis,

We’re not even trying to upload multiple files, just the one file and the DTO payload in the POST. I’ll pass this message onto the frontend team who are currently trying to figure this out. When they’re back online I’ll get them to pitch in here if this doesn’t help.

Yeah for web clients it’s the same whether it’s multiple or single file upload, they both should use multipart Content-Type.

You could post raw bytes that you can handle by having Request DTOs implement IRequiresRequestStream but JavaScript isn’t great at sending bytes.

But if you had a Request DTO with a bytes property, e.g:

public class SendRawBytes
{
    public byte[] Body { get; set; }
}

Then you could send that in JSON with the bytes serialzed with Base 64, e.g:

{"Body": "{Base64String}"}

But for web clients it’s recommended to just use standard HTTP File Uploads that’s built into browsers which is more efficient.

For what it’s worth, my team has been using FineUploader from within our AngularJS app to upload files to our ServiceStack back end for many years now.

We never bothered doing anything in plain JavaScript (although I’m sure it’s possible). We just wrote a simple custom directive that wrapped FineUploader and away we went.

There are a number of odd edge cases and browser quirks that FineUploader handles for you, so I quite recommend it.

1 Like

@codefrenzy did you ever get this working with the inbuilt servicestack js clients (i.e. using the jsclient.post<dto>(someRequestMsgObj) approach, with the files attached somehow) , or did you have to write a custom upload function in a more traditional ajax style?

Never mind, i used Typescript Servicestack-client post file and request and got it working.
Note to anyone trying this approach however: in contrast to many of the older AJAX multipart examples you will find, DO NOT put ‘Content-Type’: ‘multipart/form-data’ as a header property or it wont work! I spent so much time on this :frowning:

1 Like