Create file to Onedrive programmatically from C#?

2020-07-10 05:00发布

问题:

I want to create a doc, docx, pptx or excel file from C# direct to my Onedrive account. I have try this but it's not working for me. Anybody have any idea what I did wrong ? Thanks

public async Task<ActionResult> CreateWordFile()
{
   LiveLoginResult loginStatus = await authClient.InitializeWebSessionAsync(HttpContext);
   if (loginStatus.Status == LiveConnectSessionStatus.Connected)
   {
        var fileData = new Dictionary<string, object>();
        fileData.Add("name", "Document.docx");
        fileData.Add("Content-Type", "multipart/form-data; boundary=A300x");
        fileData.Add("type", "file");

        LiveOperationResult getResult = await connectedClient.PostAsync("me/skydrive/files", fileData);
    }

    return View();
}

EDITED: The error that I get is this one:

"The header 'Content-Type' is missing the required parameter: 'boundary'. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: Microsoft.Live.LiveConnectException: The header 'Content-Type' is missing the required parameter: 'boundary'."

回答1:

A couple of things:

  1. The dictionary provided to PostAsync only populates fields in the request body, and so adding Content-Type in there doesn't have any effect
  2. File resources are mean to be created using the UploadAsync method, which requires content. I don't believe there's an API you can call to tell the service to create a blank Office document.


回答2:

I have something else. I created an HttpWebRequest and I set some parameters. Now it create the file to my onedrive account as a docx but when I try to open the file from my account an error message appear and it's saying something like "Something wrong has happened. We could not open the file". The file exist but it can't be open.

The code that I wrote is this. Any suggestions ?

public async Task<ActionResult> CreateWordFile()
{
    string body = "--A300x\r\n"
            + "Content-Disposition: form-data; name=\"file\"; filename=\"csm.docx\"\r\n"
            + "Content-Type: application/octet-stream\r\n"
            + "\r\n"
            + "This is some content\r\n"
            + "\r\n"
            + "--A300x--\r\n";

    byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(body);
    Stream stream = new MemoryStream(fileBytes);

    LiveLoginResult loginStatus = await authClient.InitializeWebSessionAsync(HttpContext);
    if (loginStatus.Status == LiveConnectSessionStatus.Connected)
    {
        connectedClient = new LiveConnectClient(this.authClient.Session);
        string url = "https://apis.live.net/v5.0/me/skydrive/files?access_token=" + this.authClient.Session.AccessToken;


        HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
        httpWebRequest2.ContentType = "multipart/form-data; boundary=A300x";
        httpWebRequest2.Method = "POST";
        httpWebRequest2.KeepAlive = true;
        httpWebRequest2.Credentials = System.Net.CredentialCache.DefaultCredentials;
        httpWebRequest2.ContentLength = fileBytes.Length;
        Stream stream2 = httpWebRequest2.GetRequestStream();
        stream2.Write(fileBytes, 0, fileBytes.Length);
        WebResponse webResponse2 = httpWebRequest2.GetResponse();
        }

    return View();
}


回答3:

Finally I create a docx file from c#. I put here the solution (the code from the method is not refactored so it can be split in a severeal methods).

public async Task<ActionResult> CreateWordFile()
{
    LiveLoginResult loginStatus = await authClient.InitializeWebSessionAsync(HttpContext);
    if (loginStatus.Status == LiveConnectSessionStatus.Connected)
    {
        connectedClient = new LiveConnectClient(this.authClient.Session);
        string url = "https://apis.live.net/v5.0/me/skydrive/files?access_token=" + this.authClient.Session.AccessToken;

         MemoryStream streamDoc = new MemoryStream();
        DocX doc = DocX.Create(streamDoc);

        string headlineText = "Constitution of the United States";
        string paraOne = ""
            + "We the People of the United States, in Order to form a more perfect Union, "
            + "establish Justice, insure domestic Tranquility, provide for the common defence, "
            + "promote the general Welfare, and secure the Blessings of Liberty to ourselves "
            + "and our Posterity, do ordain and establish this Constitution for the United "
            + "States of America.";

        // A formatting object for our headline:
        var headLineFormat = new Formatting();
        headLineFormat.FontFamily = new System.Drawing.FontFamily("Arial Black");
        headLineFormat.Size = 18D;
        headLineFormat.Position = 12;

        // A formatting object for our normal paragraph text:
        var paraFormat = new Formatting();
        paraFormat.FontFamily = new System.Drawing.FontFamily("Calibri");
        paraFormat.Size = 10D;

        doc.InsertParagraph(headlineText, false, headLineFormat);
        doc.InsertParagraph(paraOne, false, paraFormat);

        doc.Save();

        var docFile = File(streamDoc, "application/octet-stream", "FileName.docx");
        MemoryStream streamFile = new MemoryStream();
        docFile.FileStream.Position = 0;
        docFile.FileStream.CopyTo(streamFile);

        var bites = streamFile.ToArray();
        Stream stream2 = new MemoryStream(bites);

        try
        {
            LiveOperationResult getResult = await connectedClient.UploadAsync("me/skydrive", docFile.FileDownloadName, stream2, OverwriteOption.Overwrite);
        }
        catch(WebException ex)
        {

        }
    }

    return View("~/Views/Auth/EditFile.cshtml");
}


回答4:

I also foud the answer to create an xlsx file.

public async Task<ActionResult> CreateExcelFile()
        {
            LiveLoginResult loginStatus = await authClient.InitializeWebSessionAsync(HttpContext);
            if (loginStatus.Status == LiveConnectSessionStatus.Connected)
            {
                connectedClient = new LiveConnectClient(this.authClient.Session);
                string url = "https://apis.live.net/v5.0/me/skydrive/files?access_token=" + this.authClient.Session.AccessToken;

                XSSFWorkbook wb = new XSSFWorkbook();

                // create sheet
                XSSFSheet sh = (XSSFSheet)wb.CreateSheet("Sheet1");
                // 10 rows, 10 columns
                for (int i = 0; i < 100; i++)
                {
                    var r = sh.CreateRow(i);
                    for (int j = 0; j < 100; j++)
                    {
                        r.CreateCell(j);
                    }
                }

                MemoryStream stream = new MemoryStream();
                wb.Write(stream);
                stream.Dispose();

                var arrBites = stream.ToArray();

                MemoryStream newStream = new MemoryStream(arrBites);

                var docFile = File(newStream, "application/octet-stream", "Excel.xlsx");
                MemoryStream streamFile = new MemoryStream();
                docFile.FileStream.Position = 0;
                docFile.FileStream.CopyTo(streamFile);

                var bites = streamFile.ToArray();
                Stream stream2 = new MemoryStream(bites);

                try
                {
                    LiveOperationResult getResult = await connectedClient.UploadAsync("me/skydrive", docFile.FileDownloadName, stream2, OverwriteOption.Overwrite);
                }
                catch (WebException ex)
                {

                }
            }
            return View();
        }