title: Sharing folder in Sharepoint to both external and internal users via CSOM
body: <p>For some context, I am currently building an application that will allow employees to quickly and easily upload local files to SharePoint and share them to clients by just selecting some files, inputting some emails of clients and then will be returned a link. It is mostly working, however I have run into an issue with sharing to specific users.</p>
  
  <ul>
  <li>If I share to a user that is not part of my domain, they are given a "share link". </li>
  <li>If I share to user that is part of the domain, they are given "direct access", making the share link that was generated unusable for them</li>
  <li>If I share to a user that is an external user for my domain, they are given "direct access", also making the share link unusable for them</li>
  </ul>
  
  <p>In case you dont understand what I mean by "share link", it is this section on share point:</p>
  
  <p><a href="https://i.stack.imgur.com/4zPbh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4zPbh.png" alt="enter image description here"></a></p>
  
  <p>I do not care for anonymous links as I already have an option for that in my application that is working.</p>
  
  <p>My goal is for the users to be added to the share link no matter who they are, which can be done manually (I can manually go into sharepoint, add users to both direct access and share link access), but I cannot figure out how to do that via CSOM.</p>
  
  <p>The function I have currently that generates the share link is the following:</p>
  
  <pre><code>    /// &lt;summary&gt;
      /// Creates a share link for specific users
      /// &lt;/summary&gt;
      /// &lt;param name="context"&gt;&lt;/param&gt;
      /// &lt;param name="site"&gt;full link to the folder being shared&lt;/param&gt;
      /// &lt;param name="emails"&gt;List of all emails the folder is being shared to&lt;/param&gt;
      /// &lt;param name="view"&gt;Does this user have view permissions? True = view, false = view &amp; edit&lt;/param&gt;
      /// &lt;returns&gt;The link&lt;/returns&gt;
      private string GenerateSpecificLink(ClientContext context, string site, List&lt;string&gt; emails, bool view)
      {
          var link = "Link not generated";
  
          List&lt;string&gt; successfulEmails = new List&lt;string&gt;();
  
          //Create a new link for each user as a link can only be made for one user at a time
          foreach (string email in emails)
          {
              SharingResult result = null;
              //if the user has view permissions
              if (view)
              {
                  //the sendEmail bool in the ShareDocument() function is set to false as when it is true, it will send an email to the users automatically that will end up in the spam folder most of the time
                  //by setting this to false, the user can create their own email with the link to send to the shared user, which will be of much higher quality and wont end up in a spam folder
                  result = context.Web.ShareDocument(site,
                      email,
                      ExternalSharingDocumentOption.View,
                      false,
                      "Document Shared as test");
              }
              //if the user has view &amp; edit permissions
              else
              {
                  result = context.Web.ShareDocument(site,
                      email,
                      ExternalSharingDocumentOption.Edit,
                      false,
                      "Document Shared as test");
              }
  
              //if we did successfully share the document, get the link
              //ShareLinks are in the form "fullURLLink?user", so we can just trim off the "?user" and get a link that works for *all* users that have been specified
              if (result != null)
              {
                  if(result.InvitedUsers != null)
                  {
                      link = result.InvitedUsers.First().InvitationLink;
                      int index = link.IndexOf("?");
                      if (index &gt; 0) link = link.Substring(0, index);
                      successfulEmails.Add(email);
                      _logger.LogInformation($"Generated edit link for {site}. The link works for: {string.Join(", ", successfulEmails)}");
                      _logger.LogInformation($"Share link: {link}");
                  }
                  else
                  {
                      _logger.LogWarning($"User {email} did not get an invitation link");
                  }
              }
          }
  
          if(link == "Link not generated")
          {
              return site;
          }
  
          return link;
      }
  </code></pre>
  
  <p>The Web.ShareDocument() function comes from the <a href="https://github.com/SharePoint/PnP-Sites-Core/blob/master/Core/OfficeDevPnP.Core/Extensions/ExternalSharingExtensions.cs" rel="nofollow noreferrer">OfficeDevPnP.Core ExternalSharingExtensions</a>. Ideally I would like to keep using this but if possible, I would like to find a way to force it to add all users to the share link instead of checking if they are part of the domain and if they are, giving them direct access (or even give them both direct access <em>and</em> share link access).</p>
  
  <p>If anyone has any tips on how to get this working, it would be greatly appreciated. If you need anymore information, just let me know.</p>