Search code examples
azure-active-directoryconsole-applicationsharepoint-online.net-8.0pnp-core-sdk

.NET 8.0 Console application which connect to SharePoint online using PnP Core SDK, am i doing things correctly?


I want to create a .net 8.0 console application which connect to SharePoint online tenant using PnP core SDK. now i did not find any sample code, so i developed this console application:-

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PnP.Core.Auth;
using PnP.Core.Model.SharePoint;
using PnP.Core.Services;
using PnP.Core.Services.Builder.Configuration;
using System;
using System.Security.Cryptography.X509Certificates;

namespace ConsoleApp4
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            var tenantId = "**c";
            var clientId = "7***9";
            var certificatePath = @"c:\CERT\SPDashBoard.pfx";
            var certificatePassword = "******";

            // Initialize a new service collection
            var serviceCollection = new ServiceCollection();

            // Load the certificate
            var certificate = new X509Certificate2(certificatePath, certificatePassword, X509KeyStorageFlags.Exportable);

            // Configure logging
            //serviceCollection.AddLogging(builder =>
            //{
            //    builder.AddConsole();
            //});

            // Add and configure PnP Core SDK
            serviceCollection.AddPnPCore(options =>
            {
                options.PnPContext.GraphFirst = false; // Set true if you prefer to use Graph over CSOM when possible
               // options.HttpRequests.UserAgent = "ISV|Contoso|ProductX";
                options.Sites.Add("SiteToWorkWith", new PnPCoreSiteOptions
                {
                    SiteUrl = "https://seagullssms.sharepoint.com/sites/Seagulls-PPM",
                    AuthenticationProvider = new X509CertificateAuthenticationProvider(clientId, tenantId, certificate)
                });
            });

            // Build the service provider
            var serviceProvider = serviceCollection.BuildServiceProvider();

            // Use the service provider to get the IPnPContextFactory instance
            var pnpContextFactory = serviceProvider.GetRequiredService<IPnPContextFactory>();

            // Now you can use the IPnPContextFactory to get a PnPContext and perform operations
            var context = await pnpContextFactory.CreateAsync("SiteToWorkWith");

            // Example operation: Print the title of the SharePoint site
            // Explicitly load the Title property of the Web
             await context.Web.LoadAsync(w => w.Title);

            Console.WriteLine($"Site title: {context.Web.Title}");

            // Ensure to dispose the context
            context.Dispose();
        }
    }
}

where i created an App Registration in Active Directory with self-signed certificate, and i install the certificate inside the hosting server. seems the above worked and i were able to get the web title.. but i am not sure if my approach is valid or it can be improved?


Solution

  • .NET 8.0 Console application which connect to SharePoint online using PnP Core SDK, am i doing things correctly?

    Yes, you are on the right path. You can also add error handling to your code to handle any exceptions that may occur during the authentication process or when retrieving data from SharePoint.

    Alternatively, you can also make use of Microsoft Graph API calls to access SharePoint online by using below sample code:

    Create the Azure AD application and add the required API permissions:

    enter image description here

    Here I tried to list the SharePoint site names

    using Microsoft.Identity.Client;
    using Newtonsoft.Json.Linq;
    using System.Net.Http.Headers;
    
    
    namespace ConsoleApp1
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                // Set the values for your application
                string clientId = "ClientID";
                string clientSecret = "ClientSecret";
                string tenantId = "TenantID";
                string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
    
                try
                {
                    
                    IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
                        .Create(clientId)
                        .WithClientSecret(clientSecret)
                        .WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}"))
                        .Build();
    
                    // Acquire an access token for the client
                    AuthenticationResult result = await app.AcquireTokenForClient(scopes)
                        .ExecuteAsync();
    
                    string accessToken = result.AccessToken;
    
                    using (var httpClient = new HttpClient())
                    {
                        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    
                        var response = await httpClient.GetAsync("https://graph.microsoft.com/v1.0/sites?search=*");
    
                        if (response.IsSuccessStatusCode)
                        {
                            string content = await response.Content.ReadAsStringAsync();
    
                            // Deserialize the JSON response
                            JObject json = JObject.Parse(content);
    
                            // Extract the value of the "name" property for each site
                            foreach (var site in json["value"])
                            {
                                Console.WriteLine(site["name"]);
                            }
                        }
                        else
                        {
                            Console.WriteLine($"Failed to call Microsoft Graph API: {response.ReasonPhrase}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"An error occurred: {ex.Message}");
                }
            }
        }
    }
    

    enter image description here

    Reference:

    Working with SharePoint sites in Microsoft Graph - Microsoft Graph v1.0 | Microsoft