3

I'm trying to develop a console application which will upload files from the users client PC to a SharePoint Online site.

I've written a version that used CSOM, but the file size is limited to 1.5Mb, so now I'm trying to use the REST API (it supports files up to 2Gb), however when I try to perform the upload all I get is 'forbidden'

I successfully obtain the form digest value, the code I have is

Public Shared Function UploadFile(baseURL As String, digest As CDigest, sourceFile As String) As Boolean

    Dim byteArray As Byte() = IO.File.ReadAllBytes(sourceFile)

    Dim folderName As String = "/TestFolder"
    Dim fileName As String = "Test.txt"
    Dim s As String = "/_api/web/GetFolderByServerRelativeUrl('[Folder]')/Files/add(url='[Filename]',overwrite=false)"
    s = s.Replace("[Folder]", folderName)
    s = s.Replace("[Filename]", fileName)

    Dim req As Net.HttpWebRequest = Net.HttpWebRequest.Create(baseURL & s)
    req.Method = "POST"
    req.Accept = "application/atom+xml"
    req.Headers.Add("X-RequestDigest", digest.Value)
    req.Headers.Add("binaryStringRequestBody", "true")
    req.Headers.Add("X-HTTP-Method", "PUT")

    req.ContentLength = byteArray.Length
    Dim ds As IO.Stream = req.GetRequestStream()

    ds.Write(byteArray, 0, byteArray.Length)

    ds.Close()

    Dim res As Net.HttpWebResponse = req.GetResponse() ' Errors here with Forbidden

    Console.WriteLine(CType(res, Net.HttpWebResponse).StatusDescription)

2 Answers 2

3

In fact the following CSOM examples demonstrates how to upload file those size exceeds 1,5 MB:

Example 1

Sub UploadFile(context As ClientContext, sourceFilePath As String, targetListName As String)
    Using fs As FileStream = New FileStream(sourceFilePath, IO.FileMode.Open)
        Dim fi = New FileCreationInformation()

        fi.ContentStream = fs
        fi.Url = IO.Path.GetFileName(sourceFilePath)
        fi.Overwrite = True

        Dim targetList = context.Web.Lists.GetByTitle(targetListName)
        Dim uploadFile = targetList.RootFolder.Files.Add(fi)
        context.ExecuteQuery()
    End Using
End Sub

Example 2

Using File.SaveBinaryDirect Method:

Sub UploadFile(context As ClientContext, sourceFilePath As String, targetListName As String)
    Using fs As FileStream = New FileStream(sourceFilePath, IO.FileMode.Open)

        Dim targetList = context.Web.Lists.GetByTitle(targetListName)
        context.Load(targetList.RootFolder)
        context.ExecuteQuery()
        Dim fileUrl = String.Format("{0}/{1}", targetList.RootFolder.ServerRelativeUrl, Path.GetFileName(sourceFilePath))
        Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, fileUrl, fs, True)

    End Using
End Sub

References

1

Try this

//start out by getting a client context for o365
string o365ClientId = "o365ClientId";
string o365ClientSecret = "o365ClientSecret";
//get the Uri for the personal site
Uri siteUri = new Uri(siteUrl);
//this makes a connection to o365 using an App Only token since the user is not currently connected to o365
//NOTE:  The 5 parameter version of this method is something custom I wrote, but not needed for the general
//use case; just use the standard 3 parameter version of this method that comes out of the box.  Thanks!
var token = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUri.Authority, TokenHelper.GetRealmFromTargetUrl(siteUri),o365ClientId, o365ClientSecret).AccessToken;

string uploadUrl = siteUrl + "_api/web/lists/getByTitle('Documents')/RootFolder/Files/Add(url='" + fileName + "', overwrite=false)";
//now that we have the Url and byte array, we can make a POST request to push the data to SharePoint
try
{
    //need to get the X-RequestDigest first by doing an
    //empty post to http://<site url>/_api/contextinfo
    HttpWebRequest restRqst = (HttpWebRequest)HttpWebRequest.Create(siteUrl + "_api/contextinfo");
    restRqst.Method = "POST";
    restRqst.Accept = "application/json;odata=verbose";
    restRqst.Headers.Add("Authorization", "Bearer " + token);
    restRqst.ContentLength = 0;
    //get the response so we can read in the request digest value
    HttpWebResponse restResponse = (HttpWebResponse)restRqst.GetResponse();
    Stream postStream = restResponse.GetResponseStream();
    StreamReader postReader = new StreamReader(postStream);
    string results = postReader.ReadToEnd();
    //get the FormDigestValue node
    JavaScriptSerializer jss = new JavaScriptSerializer();
    var d = jss.Deserialize<dynamic>(results);
    string xHeader = d["d"]["GetContextWebInformation"]["FormDigestValue"];
    //now create a new request to do the actual upload
    restRqst = (HttpWebRequest)HttpWebRequest.Create(uploadUrl);
    restRqst.Method = "POST";
    restRqst.Accept = "application/json;odata=verbose";
    restRqst.Headers.Add("Authorization", "Bearer " + token);
    restRqst.Headers.Add("X-RequestDigest", xHeader);
    restRqst.ContentLength = fileBytes.Length;
    //take the document and get it ready to upload
    postStream = restRqst.GetRequestStream();
    postStream.Write(fileBytes, 0, fileBytes.Length);
    postStream.Close();
    //do the upload
    restResponse = (HttpWebResponse)restRqst.GetResponse();
    //assuming it all works then we'll get a chunk of JSON back
    //with a bunch of metadata about the file we just uploaded
    postStream = restResponse.GetResponseStream();
    postReader = new StreamReader(postStream);
    results = postReader.ReadToEnd();
}

http://blogs.technet.com/b/speschka/archive/2014/08/01/uploading-large-files-to-sharepoint-2013-from-net-using-csom-and-rest.aspx

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.