Share via

Calling the ShareLink Sharepoint REST API Endpoint, but using the CSOM connection

Pablo Glomby 186 Reputation points
2020-09-02T17:24:48.16+00:00

I have a desktop solution that uses CSOM and I use SharePointOnlineCredentials to get authenticated.
I need to share a file but using the ShareLink endpoint. Although I could share my files using the native CSOM methods, ShareLink provides more options that are needed.

I use SharePoint Online. The way I authenticate using SharePointOnlineCredentials is the standard way (creds = new SharePointOnlineCredentials(szUserName, password);)

This is the function I use:

    private static void ShareFile(string szFileName, ClientContext context, string szLoginUrl, SharePointOnlineCredentials creds)
    {
        try
        {
            string szRelativeRemotePath;
            szRelativeRemotePath = (new Uri(szLoginUrl).AbsolutePath) ;
            string szFullRemotePath_File = "https://" + new Uri(szLoginUrl).Host + szRelativeRemotePath + szDocumentLibrary + "/Attachments/"+ szFileName;
            string szFullRemotePath_API = "https://" + new Uri(szLoginUrl).Host + szRelativeRemotePath + "_api/web/GetFileByUrl(@v)/ListItemAllFields/ShareLink?@v=";
            string szRequestURL = szFullRemotePath_API + "%27" + HttpUtility.UrlEncode(szFullRemotePath_File) + "%27";
            HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(szRequestURL);
            string response = "";
            using (var client = new WebClient())
            {
                client.Credentials = creds;
                client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
                client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
                client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
                client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT+5.0");
                var endpointUri = new Uri(szRequestURL);
                response = client.UploadString(szRequestURL, "{\"request\":{\"createLink\":true,\"settings\":{\"allowAnonymousAccess\":true,\"linkKind\":2,\"expiration\":null,\"restrictShareMembership\":false,\"updatePassword\":false,\"password\":\"\", \"description\":\"My description\", \"role\":8,\"applicationLink\":false,\"limitUseToApplication\":false}}}");
                dynamic dynObj = JsonConvert.DeserializeObject(response);
                if (dynObj == null )
                {
                    return;
                }
                string szURL= dynObj.d.ShareLink.sharingLinkInfo.Url.Value;
                Console.WriteLine("Sharing link: " + szURL);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Error sharing files: " + e.ToString());
        }
    }

The problem is that I get the 403 (Forbidden) error. If instead of calling "client.Credentials = creds;", I register an application in the Azure server, and using ADAL I get the access token and I use "client.Headers.Add("Authorization", "Bearer " + szAccessToken);" then the code works just fine.
This means that the code works fine but there is a problem with the authentication mechanism or maybe if I use a connection with the CSOM credentials then I cannot use that endpoint.
If I connect using the same mechanism but instead of calling that endpoint, I call another endpoint like _layouts/15/download.aspx to download a file, then it works fine.

So until now it smells like if the problem is in the permission that the CSOM connection uses.

Thanks

Microsoft 365 and Office | SharePoint | For business | Windows
Microsoft 365 and Office | SharePoint Server | Development
0 comments No comments

Answer accepted by question author

Baker Kong-MSFT 3,801 Reputation points Moderator
2020-09-03T03:05:34.337+00:00

Hi @Pablo Glomby ,

I understand you want to share a file in a document library (szDocumentLibrary), I did following test:

  1. prepare a test file in a library

22200-image.png

  1. Try below code:
            ClientContext clientContext = new ClientContext(SiteUrl);  
            clientContext.Credentials = new SharePointOnlineCredentials(username, securestring);  
    
            var web = clientContext.Web;  
    
            var dig=clientContext.GetFormDigestDirect();  
    
            clientContext.Load(web);  
            clientContext.ExecuteQuery();  
    
            Console.WriteLine($"{web.Title}--{dig.DigestValue}");  
    
            ShareFile(clientContext, clientContext.Credentials as SharePointOnlineCredentials,dig.DigestValue);  
    
            Console.ReadKey();  
    
        }  
    
        private static void ShareFile(ClientContext context, SharePointOnlineCredentials creds, string digest)  
        {  
            try  
            {               
                string szRequestURL = @"https://abc.sharepoint.com/sites/sbdev/_api/web/GetFileByUrl(@v)/ListItemAllFields/ShareLink?@v='/sites/sbdev/My test doc lib/license.txt'";  
    
                string response = "";  
                using (var client = new WebClient())  
                {  
                    client.Credentials = creds;  
                    client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");  
                    client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");  
                    client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");  
                    client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT+5.0");  
                    client.Headers.Add("X-RequestDigest", digest);  
    
                    var endpointUri = new Uri(szRequestURL);  
    
    
                    response = client.UploadString(szRequestURL, "{\"request\":{\"createLink\":true,\"settings\":{\"allowAnonymousAccess\":true,\"linkKind\":2,\"expiration\":null,\"restrictShareMembership\":false,\"updatePassword\":false,\"password\":\"\", \"description\":\"My description\", \"role\":8,\"applicationLink\":false,\"limitUseToApplication\":false}}}");  
                    dynamic dynObj = JsonConvert.DeserializeObject(response);  
                    if (dynObj == null)  
                    {  
                        return;  
                    }  
                    string szURL = dynObj.d.ShareLink.sharingLinkInfo.Url.Value;  
                    Console.WriteLine("Sharing link: " + szURL);  
                }  
            }  
            catch (Exception e)  
            {  
                Console.WriteLine("Error sharing files: " + e.ToString());  
            }  
        }  
    
    }  
    
    }

Result:

22150-image.png

Could you please have a try?

Best Regards,
Baker Kong


If the response is helpful, please click "Accept Answer" and upvote it.

Was this answer helpful?


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.