Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I want to upload a large file in chunks with JavaScript - i.e. using the File API to slice it, then post the slice blob to the server. I can do this like so:

Javascript:

// file is a file from an file select input element
var data = new FormData();
data.append('Slice', file.slice(start, end));
$http.post('/api/upload', data);  //I'm using AngularJS

MVC Web API Controller:

public async Task Post()
{
    var provider = new MultipartMemoryStreamProvider();
    await Request.Content.ReadAsMultipartAsync(provider);
    var stream = provider.Contents.First().ReadAsStreamAsync().Result;

Without the file slice, I can easily post JSON, and use model binding to pick it up:

Javascript:

var model = {};
model.CurrentBlock = 0;
model.FileName = file.name;
$http.post('/api/upload', model);

Server:

public class UploadModel
{
    public string CurrentBlock { get; set; }
    public string FileName { get; set; }
}

public async Task Post(UploadModel model)
{
}

What I can't figure out how to do both in a single request - post a file slice AND some JSON metadata. I can't seem to create any JSON object of model properties and blob data that will get picked up by any combination of controller method parameters for model binding. I tried things like:

public async Task<UploadModel> Post(UploadModel model, HttpPostedFileBase file)

Or adding the file blob directly to the model:

var model = {};
model.CurrentBlock = 0;
model.FileName = file.name;
model.Payload = file.slice(start, end)
$http.post('/api/upload', model);

But it never comes through. I'm sure I'm missing something simple.

share|improve this question
add comment

1 Answer

Download Fiddler and run it while doing the post. It will show you exactly what is getting posted (you might need to use your machine name instead of localhost to open the site).

You also might need to pass paramaters a bit differently:

$http.post('/api/upload?filename='+model.name, model.PayLoad);

and on the server you'll read it using something like:

HttpPostedFileBase request = Request.Files["Slice"];

Here is a link to more detailed example of how to do that: http://www.dotnetcurry.com/showarticle.aspx?ID=894

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.