2

I am new to Sharepoint. I am trying to create a folder in sharepoint shared folder and this needs to work for both on-premise as well as sharepoint online. The problem that I am facing is, it works for on-premise but fails for sharepoint online with error code '403 Forbidden'. It seems the request fails when it tries to get the Forms Digest for Sharepoint Online:

private static string GetFormDigestValue(string siteurl, NetworkCredential credentials)
{
    string newFormDigest = "";
    HttpWebRequest endpointRequest = 
        (HttpWebRequest)HttpWebRequest.Create(siteurl + "/_api/contextinfo");
    endpointRequest.Method = "POST";
    endpointRequest.ContentLength = 0;
    endpointRequest.Credentials = credentials;
    endpointRequest.Accept = "application/json;odata=verbose";

    try
    {
        HttpWebResponse endpointResponse = 
            (HttpWebResponse)endpointRequest.GetResponse();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    try
    {

        WebResponse webResp = endpointRequest.GetResponse();
        Stream webStream = webResp.GetResponseStream();
        StreamReader responseReader = new StreamReader(webStream);
        string response = responseReader.ReadToEnd();
        var j = JObject.Parse(response);
        var jObj = (JObject)JsonConvert.DeserializeObject(response);
        foreach (var item in jObj["d"].Children())
        {
            newFormDigest = item.First()["FormDigestValue"].ToString();
        }
        responseReader.Close();

    }
    catch (Exception ex)
    {

        Console.WriteLine(ex.Message);
    }

    return newFormDigest;
}

I think the problem is in the way I am passing Network Credentials, as it seems for Sharepoint Online, I need to use Claim Based Authentication. But I haven't been able to find any code sample that could help me implement it.

My question is, is it possible to change the code below to somehow get the Form Digest value and be able to successfully create folder on sharepoint online. If not, can you please point me to a code sample on stackexchange or elsewhere which could give me an idea how to do it.

As I mentioned, I cannot use sharepoint libraries, CSOM, javascript or any other third party dll since the code is being written for a CRM plug-in which is a sand-boxed environment. I can only use sharepoint Rest APIs to achieve it.

Please let me know if any explanation is required. I can post rest of the code too, but didn't since it would have made the post too long.

6

Your code needs two changes to work with both SharePoint On-Prem and SharePoint Online.

First, change the type of the second parameter from NetworkCredential to ICredentials. Second, you need to add a header value to the request.

private static string GetFormDigestValue(string siteurl, ICredentials credentials)
{
    string newFormDigest = "";
    HttpWebRequest endpointRequest = 
        (HttpWebRequest)HttpWebRequest.Create(siteurl + "/_api/contextinfo");
    endpointRequest.Method = "POST";
    endpointRequest.ContentLength = 0;
    endpointRequest.Credentials = credentials;
    endpointRequest.Accept = "application/json;odata=verbose";
    endpointRequest.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");

    /// ...
}

For SharePoint Online, you need to pass a SharePointOnlineCredentials as the second parameter. To use SharePointOnlineCredentials you'll need to a reference to the SharePoint Online version of the Client Object Model. Easiest way to get this is the Microsoft.SharePointOnline.CSOM Nuget package.

Here's some sample code that demonstrates how to create a new SharePointOnlineCredentials object.

private static ICredentials GetSharePointOnlineCredential(string siteurl)
{
    var loginName = "george@vandelay-industries.onmicrosoft.com";
    var password = "bosco";

    var securePassword = new SecureString();
    password.ToCharArray().ToList().ForEach(c => securePassword.AppendChar(c));

    var credential = new SharePointOnlineCredentials(loginName, securePassword);

    return credential;
}

Part of this answer came from information found in Invoke-SPORestMethod: Using the SharePoint Online REST API with PowerShell

  • I cannot use CSOM APIs as I am using this code in MS Dynamics CRM which is a restricted environment and does not allow third-party DLLs. But thanks anyway, I appreciate your help. – Shakti Prakash Singh Feb 3 '16 at 10:42
-1

Try REST: Creating Folder using REST and JavaScript

Further I would recommend a client side approach if you want to be compatible with future SharePoint Online (JSOM or REST).

  • As mentioned, I cannot use JS. – Shakti Prakash Singh Feb 3 '16 at 10:41
  • My mistake... I misread the topic title. Why can't you use JS? – Dave Feb 3 '16 at 11:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.