6

I had Create a web application with Azure AD authentication using Azure AD Application. I had granted all permission for SharePoint Online,Graph Api and Active Directory to the App for provisioning Site collections(creation and Deletion) which is working fine.

Now i am trying to add Spfx Web part to a Modern page. I followed the Msdn article Customizing Modern site pages which is working fine with user Context.

But in my web application i am accessing the site collections through tenant Context(https://tenant-admin.sharepoint.com) using access tokens from the Azure AD App. Now i want to know how to add spfx webpart to modern page of a specific site collection using the tenant context

Below is the code that i am trying to add the spfx webpart to modern pages using Tenant context.

 var tenant = new Tenant(spcontext);
                spcontext.Load(tenant);
                spcontext.ExecuteQuery();
                var site = tenant.GetSiteByUrl(webUrl);
                spcontext.Load(site);
                spcontext.Load(site.RootWeb);
                spcontext.ExecuteQuery();
                string pageName = "mypage.aspx";
                ClientSidePage page = ClientSidePage.Load(spcontext, pageName);
                var components = page.AvailableClientSideComponents();
                string wpName = "Intranet Manager";
                List<string> componentsnames = components.Select(k => k.Name).ToList();
                var webPartToAdd = components.Where(wp => wp.ComponentType == 1 && wp.Name == wpName).FirstOrDefault();
                if (webPartToAdd != null)
                {
                    ClientSideWebPart clientWp = new ClientSideWebPart(webPartToAdd) { Order = -1 };
                    page.AddControl(clientWp);
                }
                page.Save(pageName);
                spcontext.ExecuteQuery();

I am getting the below error

"Site https://tenant-admin.sharepoint.com does not have a sitepages library and therefore this page can't be a client side page.

Since I am using the tenant context. Can anyone guide me in right way?

Update:

Methods using for getting the Access token in the MVC Web Application. Here I am passing https://tenant-admin.sharepoint.com as the parameter for the method GetSharePointContext

public ClientContext GetSharePointContext(string SiteUrl)
{
    ClientContext spContext = null;
    try
    {
        Task<string> result = Task.Run<string>(() => GetAccessToken(SiteUrl));
        result.Wait();
        if (result != null)
        {
            spContext = TokenHelper.GetClientContextWithAccessToken(SiteUrl, result.Result);
        }

    }
    catch (System.Exception ex)
    {

    }
    return spContext;
}


  public async Task<string> GetAccessToken(string siteurl)
        {
            AuthenticationResult authenticationResult = null;
            string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
            string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
            // get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
            ClientCredential clientcred = new ClientCredential(clientId, appKey);
            try
            {
                Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authenticationContext = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext("https://login.microsoftonline.com/" + tenantID, new ADALTokenCache(signedInUserID));
                authenticationResult = await authenticationContext.AcquireTokenSilentAsync(siteurl, clientcred, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
                return authenticationResult.AccessToken;
            }
            catch (System.Exception ex)
            {
                return null;
            }
        }

2 Answers 2

1

In the samples in the articles below, when creating a new client-side page, finally save the page to the site pages library.

https://docs.microsoft.com/en-us/sharepoint/dev/solution-guidance/modern-experience-customizations-customize-pages

And there is no sitepages library in the site https://tenant-admin.sharepoint.com, it will throw the error.

So we should use the user context not the tenant context.

1
  • If it is user context it was working fine. But I want to get the context to the specific site collection from the tenant context since we are using the Azure AD App
    – TARUN
    Dec 21, 2017 at 9:04
1

As mentioned by Amy, you need to switch the context to a site collection context from the tenant context.

The sharepoint admin site doesn't have the site pages library, so its throwing that error.

You can make use of PnP's clone method to "take over" the security context of existing client context instance as below:

Modify your code as below:

var tenant = new Tenant(spcontext);
spcontext.Load(tenant);
spcontext.ExecuteQuery();
var site = tenant.GetSiteByUrl(webUrl);
spcontext.Load(site);
spcontext.Load(site.RootWeb);
spcontext.ExecuteQuery();

using (ClientContext newSiteContext = spcontext.Clone(webUrl))
{
    string pageName = "mypage.aspx";
    ClientSidePage page = ClientSidePage.Load(newSiteContext, pageName);
    var components = page.AvailableClientSideComponents();
    string wpName = "Intranet Manager";
    List<string> componentsnames = components.Select(k => k.Name).ToList();
    var webPartToAdd = components.Where(wp => wp.ComponentType == 1 && wp.Name == wpName).FirstOrDefault();
    if (webPartToAdd != null)
    {
        ClientSideWebPart clientWp = new ClientSideWebPart(webPartToAdd) { Order = -1 };
        page.AddControl(clientWp);
    }
    page.Save(pageName);
    newSiteContext.ExecuteQuery();
}
11
  • I am Getting the error "The remote server returned an error: (401) Unauthorized." at the line ClientSidePage page = ClientSidePage.Load(newSiteContext, pageName);
    – TARUN
    Dec 26, 2017 at 4:34
  • If it tenant context created with user credentials, the clone was working fine. If the context is created with Access token from the Azure AD app I am getting the above 401 error.
    – TARUN
    Dec 26, 2017 at 9:33
  • Could be something wrong with Azure AD configuration/permission ? Since it works with User credentials, looks to be some config issue Jan 1, 2018 at 7:27
  • With the same Azure AD configuration, I am able to create Site collections, lists etc.. The only issue I am not able to clone the context
    – TARUN
    Jan 1, 2018 at 9:23
  • ok but why are you loading tenant context in the first place ? why not directly load site collection context ? Jan 1, 2018 at 10:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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