Search code examples
c#file-uploadmicrosoft-graph-apihttp-headersdotnet-httpclient

MS Graph API PUT Error - Entity only allows writes with a JSON Content-Type header


I’m trying to upload an Excel file to a drive location via MS Graph API and it seems my code is not correct when providing the content type and calling Async with payload.

        static public string DecodeData(string encodedData)
        {
            byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
            string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
            return returnValue;
        }
        // Upload files to SharePoint
        public void SharePointUploadDriveItems(string accessToken, string driveId)
        {
            try
            {
                string path = @"C:\\StockLevelReportLocation\\New Files\\TestFileUpload.xlsx";
                byte[] filebytes = System.IO.File.ReadAllBytes(path);

                using (var httpClient = new HttpClient())
                {
                    //httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                    //httpClient.DefaultRequestHeaders.Add("ContentType", "application/json;odata.metadata=verbose");

                    using (var request = new HttpRequestMessage(HttpMethod.Put, "https://graph.microsoft.com/v1.0/drives/" + driveId + "/root:/Oks/Stock Report/TestFileUpload.xlsx:/conten"))
                    {
                        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                        request.Headers.Add("ContentType", "application/json;odata.metadata=verbose");

                        request.Content = new StringContent(DecodeData(Convert.ToBase64String(filebytes)), System.Text.Encoding.ASCII, "text/plain");
                        var driveItemsResponse = httpClient.SendAsync(request).Result;
                        var driveItemsResponseContent = driveItemsResponse.Content.ReadAsStringAsync().Result;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(Exception - " + ex.ToString());
            }
        }

Error - {"error":{"code":"BadRequest","message":"Entity only allows writes with a JSON Content-Type header.","innerError":{"date":"2023-08-17T04:49:03","request-id":"66e43a8d-eb4-4ea9-b99f-27b4b","client-request-id":"66e43a8d-eb4-4ea9-b99f-27b4b"}}}

Appreciate it if you can recreate the scenario and provide me with a solution.


Solution

  • I believe you can upload directly the file stream. No need to specify content type header in this case.

    public void SharePointUploadDriveItems(string accessToken, string driveId)
    {
        try
        {
            string path = @"C:\StockLevelReportLocation\New Files\TestFileUpload.xlsx";
    
            using var fileStream = File.OpenRead(path);
            using (var httpClient = new HttpClient())
            {
                using (var request = new HttpRequestMessage(HttpMethod.Put, "https://graph.microsoft.com/v1.0/drives/" + driveId + "/root:/Oks/Stock Report/TestFileUpload.xlsx:/content"))
                {
                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    
                    request.Content = new StreamContent(fileStream);
                    var driveItemsResponse = httpClient.SendAsync(request).Result;
                    var driveItemsResponseContent = driveItemsResponse.Content.ReadAsStringAsync().Result;
                }
            }
        }
        catch (Exception ex)
        {
            //throw new Exception(Exception - " + ex.ToString());
        }
    }