'Docx to pdf in Microsoft Graph Api failing with error "WordCantOpenDocument"

We are doing a docx-PDF conversion by uploading a Word-document(docx) by first uploading it using the large document upload in Microsoft Graph API (link) and after that downloading it to PDF-format (link)

The documents are modified using Open XML SDK for .NET. Mostly the whole process works fine but sometimes we get issues that we believe to be due to some XML-formatting within the documents. The error that we then get from the endpoint is:

Inner error: OfficeConversion_BadRequest

ErrorCode: WordCantOpenDocument

The actual Word-documents can be opened manually with no issues and even exported to PDF using the built in solution in Microsoft Word, but for some reason the conversion fails when doing this through the Graph endpoint.

The errors are, as you can see, quite non-informative and I'm wondering if there are any ways of investigating the issues any further and maybe get more logging information from MSFT?



Solution 1:[1]

You can follow the below steps using Microsoft Graph API to convert the format of your documents:

  1. Create a native app in Azure portal and give permissions, for Graph API._

  2. Create a Console Application, add two dlls and their references:_

DLLs:. These can be added as Nuget packages.
Microsoft.IdentityModel.Clients.ActiveDirectory.dll (Nuget Package Microsoft.SharePointOnline.CSOM)
Newtonsoft.Json.dll (Nuget Package Newtonsoft.Json)

Add the below using statements :

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json;

  1. Implement the code, with Graph Api to convert the document and download it locally and upload it back to SPO site:
    Note: ADAL library is used for authentication.

--

using Microsoft.IdentityModel.Clients.ActiveDirectory;  
using Newtonsoft.Json;  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Net.Http;  
using System.Net.Http.Headers;  
using System.Security.Cryptography.X509Certificates;  
using System.Text;  
using System.Threading.Tasks;  
using System.Net;  
using System.Security.Claims;  
using System.IO;  
using Microsoft.SharePoint.Client;  
using System.Security;  
  
  
namespace ConsoleApp1  
{  
public static class StreamExtensions  
{  
public static byte[] ReadAllBytes(this Stream instream)  
{  
if (instream is MemoryStream)  
return ((MemoryStream)instream).ToArray();  
  
using (var memoryStream = new MemoryStream())  
{  
instream.CopyTo(memoryStream);  
return memoryStream.ToArray();  
}  
}  
}  
class Program  
{  
private static string TENANT_NAME = "mycompany.onmicrosoft.com";  
private static string resource = "[https://graph.microsoft.com](https://graph.microsoft.com/)";  
private static string loginname = "[email protected]";  
private static string loginpassword = "*********";  
private static string AzureTenantID = "********-f247-4d48-a45d-************";  
private static string spositeUrl = "[https://mycompany.sharepoint.com/*********](https://mycompany.sharepoint.com/*********)";  
private static string destinationDocumentLibrary = "dl1";  
  
static void Main(string[] args)  
{  
//USER TOKEN - THIS WORKS!!!!!!!!!!!!  
UserPasswordCredential userPasswordCredential = new UserPasswordCredential(loginname, loginpassword);  
var graphauthority = "[https://login.microsoftonline.com/](https://login.microsoftonline.com/)" + AzureTenantID;  
AuthenticationContext authContext = new AuthenticationContext(graphauthority);  
var token = authContext.AcquireTokenAsync(resource, "94b1544c-35e8-4d45-a941-c3dbaab283dc", userPasswordCredential).Result.AccessToken;  
  
// Create a new HttpWebRequest Object to the mentioned URL.  
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create("[https://graph.microsoft.com/v1.0/me/drive/root:/orange.docx:/content?format=pdf](https://graph.microsoft.com/v1.0/me/drive/root:/orange.docx:/content?format=pdf)");  
//HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create("[https://graph.microsoft.com/v1.0/drives/b!zMNDej1sNEG0SanRDltXfAVTYcdt1pdIggMBPYZYp9Wgdi3ir9sFQJXof6...](https://graph.microsoft.com/v1.0/drives/b!zMNDej1sNEG0SanRDltXfAVTYcdt1pdIggMBPYZYp9Wgdi3ir9sFQJXof6j8GNUD/root:/Repro.docx:/content?format=pdf)");  
myHttpWebRequest.AllowAutoRedirect = false;  
myHttpWebRequest.Headers.Set("Authorization", ("Bearer " + token));  
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();  
string downloadPath = myHttpWebResponse.GetResponseHeader("Location");  
Console.WriteLine("Download PDF file from here:\n " + downloadPath);  
  
//Get the file Stream with Location Url  
HttpWebRequest HttpWebRequest_download = (HttpWebRequest)WebRequest.Create(downloadPath);  
HttpWebRequest_download.Accept = "blob";  
  
var response = (HttpWebResponse)HttpWebRequest_download.GetResponse();  
Stream myStream = response.GetResponseStream();  
FileStream targetFile = new FileStream("C:\\temp\\orange_converted_localcopy.pdf", FileMode.Create);  
myStream.CopyTo(targetFile);  
myStream.Close();  
response.Close();  
  
//You can continue to use Graph API to upload document back to OneDrive or other SPO site  
//since we used loginname/password above already, we will use simple CSOM to upload file to another SPO site as quick demo  
using (var clientContext = new ClientContext(spositeUrl))  
{  
SecureString passWord = new SecureString();  
foreach (char c in loginpassword.ToCharArray()) passWord.AppendChar(c);  
  
clientContext.Credentials = new SharePointOnlineCredentials(loginname, passWord);  
var web = clientContext.Web;  
clientContext.Load(web);  
clientContext.ExecuteQuery();  
  
List dl = web.Lists.GetByTitle(destinationDocumentLibrary);  
clientContext.Load(dl);  
clientContext.ExecuteQuery();  
  
//Upload the converted file to SPO site  
targetFile.Position = 0;  
var fci = new FileCreationInformation  
{  
Url = "orange_converted_spocopy.pdf",  
ContentStream = targetFile,  
Overwrite = true  
};  
Folder folder = dl.RootFolder;  
FileCollection files = folder.Files;  
Microsoft.SharePoint.Client.File file = files.Add(fci);  
clientContext.Load(files);  
clientContext.Load(file);  
clientContext.ExecuteQuery();  
  
targetFile.Close();  
response.Close();  
  
Console.WriteLine("Converted file is uploaded to SPO site - orange_converted_spocopy.pdf");  
Console.ReadKey();  
}  
}  
  
}  
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 RajkumarMamidiChettu-MT