0

I want to upload a file from a URL to Sharepoint Online. I looked up various classes and the one I found which looked good was WebClient, I've tried to pull a file which has been uploaded to my app web into a stream and then upload that stream to my target list in Sharepoint but all I get is a "403 Forbidden" exception.

    WebClient wc = new WebClient(); 
    wc.UseDefaultCredentials = true;
    wc.Headers.Add("User-Agent:Other");
        byte[] response = wc.DownloadData
("www.mysite-12345.sharepoint.com/sites/dev/myapp/lists/doclib/themefile.spfont");

        var uploadUrl = 
"www.mysite.sharepoint.com/_catalogs/theme/15/themefile.spfont";

        wc.UploadData
("www.mysite.sharepoint.com/_catalogs/theme/15/themefile.spfont", "POST", response);                       
  }

If someone can give me some advice as to where I'm going wrong or an alternative method to upload my file I would really appreciate it.

Junior
  • 315
  • 2
  • 5
  • 9

1 Answers1

1

I guess you need not only to upload a file into SharePoint Online but to copy a from one site into another, right?

There are several ways of downloading/uploading a file in SharePoint, you could utilize specific SharePoint APIs like CSOM for that purpose or vanilla .NET capabilities (e.g. HttpClient Class, WebClient Class) as demonstrated below:

var sourceWebUri = new Uri("https://sourcesite.sharepoint.com");
var targetWebUri = new Uri("https://targetsite.sharepoint.com");
var userName = "username@tenant.onmicrosoft.com";
var password = "password";

using(var sourceClient = GetClient(sourceWebUri,userName,password))
{
    var fileContent = sourceClient.DownloadData(sourceWebUri + "/documents/SharePoint User Guide.docx");
    using(var targetClient = GetClient(targetWebUri,userName,password))
    {
         targetClient.UploadData(targetWebUri + "/documents/SharePoint User Guide.docx,"PUT" ,fileContent);
    }
 }

where

    private static WebClient GetClient(Uri webUri, string userName, string password)
    {
        var client = new WebClient();
        client.Credentials = GetCredentials(webUri, userName, password);
        client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
        return client;
    }


    private static SharePointOnlineCredentials GetCredentials(Uri webUri, string userName, string password)
    {
        var securePassword = new SecureString();
        foreach (var ch in password) securePassword.AppendChar(ch);
        return new SharePointOnlineCredentials(userName, securePassword);
    }

How to copy a file between sites in SharePoint Online via CSOM API

SharePoint CSOM API contains File.OpenBinaryDirect method that is intended for downloading a file from SharePoint and File.SaveBinaryDirect method for uplading a file into SharePoint, the following example demonstrates how to copy a file between sites:

public static void CopyFile(ClientContext sourceCtx, string sourceFileUrl, ClientContext targetCtx, string targetFileUrl)
{
    if (sourceCtx.HasPendingRequest)
       sourceCtx.ExecuteQuery();
    using (var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(sourceCtx, sourceFileUrl))
    {
        Microsoft.SharePoint.Client.File.SaveBinaryDirect(targetCtx, targetFileUrl, fileInfo.Stream, true);
    }
}

Usage

using (var sourceCtx = GetSPOContext(sourceWebUri, userName, password))
{
     using (var targetCtx = GetSPOContext(targetWebUri, userName, password))
     {
          CopyFile(sourceCtx, "/sourcesite/documents/SharePoint User Guide.docx", targetCtx, "/targetsite/documents/SharePoint User Guide.docx");
     }
}

where

public static ClientContext GetSPOContext(Uri webUri, string userName, string password)
{
     var securePassword = new SecureString();
     foreach (var ch in password) securePassword.AppendChar(ch);
     return new ClientContext(webUri) { Credentials = new SharePointOnlineCredentials(userName, securePassword) };
}

Prerequisites

SharePointOnlineCredentials class:

Represents an object that provides credentials to access SharePoint Online resources.

is a part of SharePoint Online Client Components SDK

Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193
  • Hi Vadim, thanks for the detailed response. Would it be possible to use a Client Context and use the current logged in user to authenticate or do we need to explicitly pass credentials? – Junior Mar 22 '15 at 23:33
  • 1
    In addition to specifying user credentials explicitly there is another way to request permission to access SharePoint called OAuth flow, follow this article for a more details https://msdn.microsoft.com/en-us/library/office/jj687470.aspx – Vadim Gremyachev Mar 23 '15 at 08:32