Ted Benson
Ted Benson

Reputation: 55

File Corruption when Uploading Excel files to Microsoft Graph API Beta

We're trying to upload Microsoft Excel file to OneDrive but the file gets corrupted every time we do so.

We've tried using [these instructions] to make a PUT request to the following permutations of settings:

Content-Encodings:

POST bodies:

If we download the file that gets uploaded, it looks almost the same, but a few binary regions are different.

If you feel comfortable opening an Excel file off the internet, I've uploaded an example of the file we upload and the corrupted file OneDrive saves.

This has all the smell of a bug that can be fixed with a single parameter modification... I just can't figure out what it is.

Anyone have thoughts? Thanks!

Upvotes: 2

Views: 1708

Answers (2)

Ted Benson
Ted Benson

Reputation: 798

Thanks @GSM. Here's our code in TypeScript.

var fileContent = FileSystem.readFileSync(localFile);
var url = `https://graph.microsoft.com/beta/me/drive/root/children/${doc.name}.xlsx:/content`,

var opts {
  url: url,
  method: 'PUT',
  headers: [
    'Content-Type': 'text/plain',
    'Authorization': token
  ],
  body: fileContent
};
var requestOpts = {
  url: `https://${domain}${opts.path}`,
  method: opts.method,
  headers: {},
};

request(opts, cb);

The only difference I see is that you're using an alternate path to upload the file, which is also documented on the GraphAPI page. If we use the path you're using we get back the back the error message:

{
  "error": {
    "code": "BadRequest",
    "message": "Entity only allows writes with a JSON Content-Type header.",
    "innerError": {
      "request-id": "2a2e7588-3217-4337-bee3-f8aff208510c",
      "date": "2016-05-30T16:35:50"
    }
  }
}

..which is strange because it makes me expect that your code shouldn't have worked either.

Update -- the answer

By reading the file into a string and then writing it to the JSON object that defined the PUT parameters, we were corrupting it. We solved the problem by simply piping a file read stream right to the open HTTP request.

Upvotes: 1

Saca
Saca

Reputation: 10652

It would be easier to help if you posted your code. However, here's some code that can be used to upload files to OneDrive. I tested it with your file and was able to upload and download just fine:

using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + t.AccessToken);

    var byteContent = File.ReadAllBytes(@"C:\Temp\sheet-uploaded.xlsx");
    var url = resource + "beta/me/drive/root:/Documents/sheet-uploaded.xlsx:/content";

    var result = client.PutAsync(url, new ByteArrayContent(byteContent)).Result;
    result.Content.ReadAsStringAsync().Dump();
}

Upvotes: 1

Related Questions