Example #1
0
        public static async Task Main(string[] args)
        {
            var host = Host.CreateDefaultBuilder()

                       // Ensure you do consent to the PnP App when using another tenant (update below url to match your aad domain):
                       // https://login.microsoftonline.com/a830edad9050849523e17050400.onmicrosoft.com/adminconsent?client_id=31359c7f-bd7e-475c-86db-fdb8c937548e&state=12345&redirect_uri=https://www.pnp.com
                       // .UseEnvironment("officedevpnp")
                       .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddEventSourceLogger();
                logging.AddConsole();
            })
                       .ConfigureServices((hostingContext, services) =>
            {
                // Read the custom configuration from the appsettings.<environment>.json file
                var customSettings = new CustomSettings();
                hostingContext.Configuration.Bind("CustomSettings", customSettings);

                // Add the PnP Core SDK services
                services.AddPnPCore(options => {
                    // You can explicitly configure all the settings, or you can
                    // simply use the default values

                    options.PnPContext.GraphFirst = true;
                    //options.PnPContext.GraphCanUseBeta = true;
                    //options.PnPContext.GraphAlwaysUseBeta = false;

                    //options.HttpRequests.UserAgent = "NONISV|SharePointPnP|PnPCoreSDK";
                    //options.HttpRequests.MicrosoftGraph = new PnPCoreHttpRequestsGraphOptions
                    //{
                    //    UseRetryAfterHeader = true,
                    //    MaxRetries = 10,
                    //    DelayInSeconds = 3,
                    //    UseIncrementalDelay = true,
                    //};
                    //options.HttpRequests.SharePointRest = new PnPCoreHttpRequestsSharePointRestOptions
                    //{
                    //    UseRetryAfterHeader = true,
                    //    MaxRetries = 10,
                    //    DelayInSeconds = 3,
                    //    UseIncrementalDelay = true,
                    //};

                    //options.DefaultAuthenticationProvider = authenticationProvider;

                    options.Sites.Add("DemoSite",
                                      new PnP.Core.Services.Builder.Configuration.PnPCoreSiteOptions
                    {
                        SiteUrl = customSettings.DemoSiteUrl
                    });
                });

                // PnP Core Authentication
                // To check out more authentication options check out the documentation for more information:
                //  https://pnp.github.io/pnpcore/using-the-sdk/configuring%20authentication.html
                services.AddPnPCoreAuthentication(
                    options =>
                {
                    options.Credentials.Configurations.Add("interactive",
                                                           new PnP.Core.Auth.Services.Builder.Configuration.PnPCoreAuthenticationCredentialConfigurationOptions
                    {
                        ClientId    = customSettings.ClientId,
                        TenantId    = customSettings.TenantId,
                        Interactive = new PnP.Core.Auth.Services.Builder.Configuration.PnPCoreAuthenticationInteractiveOptions
                        {
                            RedirectUri = customSettings.RedirectUri
                        }
                    });

                    options.Credentials.Configurations.Add("credentials",
                                                           new PnP.Core.Auth.Services.Builder.Configuration.PnPCoreAuthenticationCredentialConfigurationOptions
                    {
                        ClientId    = customSettings.ClientId,
                        TenantId    = customSettings.TenantId,
                        Interactive = new PnP.Core.Auth.Services.Builder.Configuration.PnPCoreAuthenticationInteractiveOptions
                        {
                            RedirectUri = customSettings.RedirectUri
                        }
                        //},
                        //CredentialManager = new PnP.Core.Auth.Services.Builder.Configuration.PnPCoreAuthenticationCredentialManagerOptions
                        //{
                        //    CredentialManagerName = customSettings.CredentialManager
                        //}
                    });

                    // Configure the default authentication provider
                    options.Credentials.DefaultConfiguration = "interactive";

                    // Map the site defined in AddPnPCore with the
                    // Authentication Provider configured in this action
                    options.Sites.Add("DemoSite",
                                      new PnP.Core.Auth.Services.Builder.Configuration.PnPCoreAuthenticationSiteOptions
                    {
                        AuthenticationProviderName = "interactive"
                    });
                });
            })
                       // Let the builder know we're running in a console
                       .UseConsoleLifetime()
                       // Add services to the container
                       .Build();

            await host.StartAsync();

            using (var scope = host.Services.CreateScope())
            {
                var pnpContextFactory = scope.ServiceProvider.GetRequiredService <IPnPContextFactory>();

                #region Interactive GET's
                using (var context = await pnpContextFactory.CreateAsync("DemoSite"))
                {
                    // ================================================================
                    // Getting data - everything is async!
                    // Same programming model, regardless of wether under the covers Microsoft Graph is used or SharePoint REST

                    // Interactive GET samples

                    // Retrieving web with lists and masterpageurl loaded ==> SharePoint REST query
                    var web = await context.Web.GetAsync(p => p.Title, p => p.Lists, p => p.MasterUrl);

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===Web (REST)===");
                    Console.WriteLine($"Title: {web.Title}");
                    Console.WriteLine($"# Lists: {web.Lists.Length}");
                    Console.WriteLine($"Master page url: {web.MasterUrl}");
                    Console.ResetColor();

                    // Getting the team connected to this Modern Team site ==> Microsoft Graph query
                    var team = await context.Team.GetAsync();

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===Team (Graph v1)===");
                    Console.WriteLine($"Name: {team.DisplayName}");
                    Console.WriteLine($"Visibility: {team.Visibility}");
                    Console.WriteLine($"Funsettings.AllowGiphy: {team.FunSettings.AllowGiphy}");
                    Console.ResetColor();

                    // Getting a specific list and loading it's items
                    var demo1List = web.Lists.FirstOrDefault(p => p.Title == "Demo1");
                    if (demo1List != null)
                    {
                        // Load list items
                        await demo1List.GetAsync(p => p.Items);

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("===List (Graph v1)===");
                        Console.WriteLine($"Title: {demo1List.Title}");
                        Console.WriteLine($"# Items: {demo1List.Items.Length}");
                        Console.ResetColor();
                    }

                    // Getting the messages in the default team channel, first ensure
                    await team.LoadAsync(p => p.PrimaryChannel);

                    await team.PrimaryChannel.LoadAsync(p => p.Messages);

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===Team channel messages (Graph beta)===");
                    Console.WriteLine($"Title: {team.PrimaryChannel.DisplayName}");
                    Console.WriteLine($"# Messages: {team.PrimaryChannel.Messages.Length}");
                    Console.ResetColor();
                }
                #endregion

                #region Linq query support!
                using (var context = pnpContextFactory.Create("DemoSite"))
                {
                    context.GraphFirst = false;

                    // We can retrieve the whole list of lists
                    // and their items in the context web
                    var listsQuery = (from l in context.Web.Lists.QueryProperties(l => l.Id, l => l.Title, l => l.Description)
                                      orderby l.Title descending
                                      select l);

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===LINQ: Retrieve list and list items===");
                    foreach (var list in listsQuery.ToList())
                    {
                        Console.WriteLine($"{list.Id} - {list.Title} - Items count: {list.Items.Length}");
                    }
                    Console.ResetColor();
                }

                using (var context = pnpContextFactory.Create("DemoSite"))
                {
                    // Or we can easily get a specific list
                    var demo1List = context.Web.Lists.GetByTitle("Site Assets", l => l.Id, l => l.Title, l => l.Description);

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===LINQ: Retrieve specific list===");
                    Console.WriteLine($"Just got list '{demo1List.Title}' with ID '{demo1List.Id}'");
                    Console.ResetColor();
                }

                using (var context = pnpContextFactory.Create("DemoSite"))
                {
                    // We can retrieve items of a specific list
                    // eventually partitioning the results

                    //TODO: Disabled pending issue with paging.

                    //var itemsQuery = (from i in context.Web.Lists.GetByTitle("Site Assets").Items
                    //                  select i).Take(2).Skip(1);

                    //Console.ForegroundColor = ConsoleColor.Yellow;
                    //Console.WriteLine("===LINQ: Retrieve specific list with partitioned items===");
                    //foreach (var item in itemsQuery)
                    //{
                    //    Console.WriteLine($"Item with title '{item.Title}' has ID: {item.Id}");
                    //}
                    //Console.ResetColor();
                }

                using (var context = pnpContextFactory.Create("DemoSite"))
                {
                    // Or we can retrieve a specific item
                    // TODO: Issue with Cascading sychronous loads
                    //var listItem = context.Web.Lists.GetByTitle("Site Assets").Items.GetById(1);

                    //Console.ForegroundColor = ConsoleColor.Yellow;
                    //Console.WriteLine("===LINQ: Retrieve list item by id===");
                    //Console.WriteLine($"Item with title '{listItem.Title}' has ID: {listItem.Id}");
                    //Console.ResetColor();
                }

                using (var context = pnpContextFactory.Create("DemoSite"))
                {
                    // Or we can retrieve a specific document from a library
                    var document = context.Web.Lists.GetByTitle("Site Assets").Items
                                   .QueryProperties(i => i.Id, i => i.Title)
                                   .Where(i => i.Title == "__siteIcon__.png")
                                   .FirstOrDefault();

                    if (document != null)
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("===LINQ: Retrieve document by title===");
                        Console.WriteLine($"Document with title '{document.Title}' has ID: {document.Id}");
                        Console.ResetColor();
                    }
                }
                #endregion

                #region Add/Update/Delete/Batching
                using (var context = pnpContextFactory.Create("DemoSite"))
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===ADD/UPDATE/DELETE: create/delete list and add 20 items in batch===");
                    Console.ResetColor();
                    // Check if lists exists and delete first if needed
                    var newList = context.Web.Lists.GetByTitle("AddTest", l => l.Id, l => l.Title, l => l.Description);
                    if (newList != null)
                    {
                        await newList.DeleteAsync();
                    }
                    // Add the new list
                    newList = await context.Web.Lists.AddAsync("AddTest", ListTemplateType.GenericList);

                    // In batch add 20 items
                    for (int i = 0; i < 20; i++)
                    {
                        Dictionary <string, object> listItem = new Dictionary <string, object>
                        {
                            { "Title", $"Item {i}" }
                        };

                        await newList.Items.AddBatchAsync(listItem);
                    }
                    await newList.LoadBatchAsync(context.CurrentBatch, p => p.Items, p => p.NoCrawl);

                    // Send 20 adds + reload as a single operation (=batch) to server
                    await context.ExecuteAsync();

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine($"List with title '{newList.Title}' has {newList.Items.Length} items");
                    Console.ResetColor();

                    // Update item
                    var itemToUpdate = newList.Items.FirstOrDefault();
                    itemToUpdate.Values["Title"] = $"Updated at {DateTime.UtcNow}";
                    await itemToUpdate.UpdateAsync();

                    // Update item using dynamic syntax
                    //dynamic itemToUpdateDynamic = itemToUpdate;
                    //itemToUpdateDynamic["Title"] = $"Updated again at {DateTime.UtcNow}";
                    //await itemToUpdateDynamic.UpdateAsync();

                    //dynamic itemToUpdate = listToAdd.Items.FirstOrDefault();
                    //itemToUpdate.Title = $"Updated at {DateTime.UtcNow}";
                    //await itemToUpdate.UpdateAsync();

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===ADD/UPDATE/DELETE: Add and configure a team channel===");
                    Console.ResetColor();

                    // Get team channels and primary channel
                    var team = await context.Team.GetAsync(p => p.Channels,
                                                           p => p.PrimaryChannel, p => p.FunSettings);

                    // Ensure the needed properties were loaded
                    await team.PrimaryChannel.EnsurePropertiesAsync(p => p.DisplayName, p => p.Tabs, p => p.Messages);

                    // Add/Delete a new tab in the primary channel
                    var pnpTab = team.PrimaryChannel.Tabs.AsRequested().FirstOrDefault(p => p.DisplayName == "PnPTab");
                    if (pnpTab != null)
                    {
                        await pnpTab.DeleteAsync();

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("Deleted tab PnPTab");
                        Console.ResetColor();
                    }

                    await team.PrimaryChannel.Tabs.AddDocumentLibraryTabAsync("PnPTab", new Uri($"{context.Uri}/Shared Documents"));

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Added tab PnPTab");
                    Console.ResetColor();

                    // Update the fun settings of the team
                    team.FunSettings.AllowGiphy = !team.FunSettings.AllowGiphy;
                    await team.UpdateAsync();

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Updated team fun settings");
                    Console.ResetColor();


                    // Add a message in the general channel
                    await team.PrimaryChannel.Messages.AddAsync($"PnP rocks - {DateTime.UtcNow}");

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Added a message to the primary channel");
                    Console.ResetColor();
                }
                #endregion

                #region Paging
                using (var context = pnpContextFactory.Create("DemoSite"))
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===Paging support===");
                    Console.ResetColor();

                    // Get team channels and primary channel
                    var team = await context.Team.GetAsync(p => p.PrimaryChannel);

                    await team.PrimaryChannel.EnsurePropertiesAsync(p => p.Messages);

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine($"Current number of messages: {team.PrimaryChannel.Messages.Length}");
                    Console.ResetColor();

                    if (team.PrimaryChannel.Messages.Length > 0)
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("===Next page loaded==");
                        Console.WriteLine($"Current number of messages: {team.PrimaryChannel.Messages.Take(2).AsEnumerable().Count()}");
                        Console.ResetColor();

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("===Next page loaded==");
                        Console.WriteLine($"Current number of messages: {team.PrimaryChannel.Messages.Take(2).Skip(2).AsEnumerable().Count()}");
                        Console.ResetColor();

                        Console.WriteLine("===All pages loaded==");
                        Console.WriteLine($"Current number of messages: {team.PrimaryChannel.Messages.Length}");
                        Console.ResetColor();
                    }
                }
                #endregion

                #region Pages API

                var pageName = $"Page-{Guid.NewGuid().ToString("N")}.aspx";

                // Create a modern page
                using (var context = await pnpContextFactory.CreateAsync("DemoSite"))
                {
                    var page = await context.Web.NewPageAsync();

                    // A simple section and text control to the page
                    page.AddSection(CanvasSectionTemplate.TwoColumnRight, 1);
                    page.AddControl(page.NewTextPart("PnP"), page.Sections[0].Columns[0]);

                    // and a countdown web part
                    var availableComponents = await page.AvailablePageComponentsAsync();

                    var countdownWebPartComponent = availableComponents.FirstOrDefault(p => p.Id == page.DefaultWebPartToWebPartId(DefaultWebPart.CountDown));
                    var countdownWebPart          = page.NewWebPart(countdownWebPartComponent);

                    // Read the json settings for the countdown web part
                    countdownWebPart.PropertiesJson = await new StreamReader(@"..\..\..\countdownWebPart.json").ReadToEndAsync();
                    page.AddControl(countdownWebPart, page.Sections[0].Columns[1]);

                    // Set the page title
                    page.PageTitle = "Modern Page created with PnP Core SDK";

                    // Save the page
                    await page.SaveAsync(pageName);

                    // And publish it
                    await page.PublishAsync();

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===Modern Pages API (REST)===");
                    Console.WriteLine($"Page Title: {page.PageTitle}");
                    Console.WriteLine($"# Page Name: {pageName}");
                    Console.ResetColor();
                }

                // Inspect a modern page
                using (var context = await pnpContextFactory.CreateAsync("DemoSite"))
                {
                    var page = (await context.Web.GetPagesAsync(pageName)).FirstOrDefault();

                    // Read the Countdown Web Part Configuration
                    var countdownWebPartJson = page.Sections[0].Controls[1].JsonControlData;

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("===Modern Pages API (REST)===");
                    Console.WriteLine($"Image Web Part Configuraiton");
                    Console.WriteLine(countdownWebPartJson);
                    Console.ResetColor();
                }

                #endregion
            }

            host.Dispose();
        }
Example #2
0
        public static async Task Main(string[] args)
        {
            var host = Host.CreateDefaultBuilder()

                       // Ensure you do consent to the PnP App when using another tenant (update below url to match your aad domain):
                       // https://login.microsoftonline.com/a830edad9050849523e17050400.onmicrosoft.com/adminconsent?client_id=31359c7f-bd7e-475c-86db-fdb8c937548e&state=12345&redirect_uri=https://www.pnp.com
                       //.UseEnvironment("officedevpnp")
                       .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddEventSourceLogger();
                logging.AddConsole();
            })
                       .ConfigureServices((hostingContext, services) =>
            {
                // Read the custom configuration from the appsettings.<environment>.json file
                var customSettings = new CustomSettings();
                hostingContext.Configuration.Bind("CustomSettings", customSettings);

                // Create an instance of the Authentication Provider that uses Credential Manager
                //var authenticationProvider = new CredentialManagerAuthenticationProvider(
                //                customSettings.ClientId,
                //                customSettings.TenantId,
                //                customSettings.CredentialManager);

                var authenticationProvider = new InteractiveAuthenticationProvider(
                    customSettings.ClientId,
                    customSettings.TenantId,
                    customSettings.RedirectUri);

                // Add the PnP Core SDK services
                services.AddPnPCore(options => {
                    // You can explicitly configure all the settings, or you can
                    // simply use the default values

                    //options.PnPContext.GraphFirst = true;
                    //options.PnPContext.GraphCanUseBeta = true;
                    //options.PnPContext.GraphAlwaysUseBeta = false;

                    //options.HttpRequests.UserAgent = "NONISV|SharePointPnP|PnPCoreSDK";
                    //options.HttpRequests.MicrosoftGraph = new PnPCoreHttpRequestsGraphOptions
                    //{
                    //    UseRetryAfterHeader = true,
                    //    MaxRetries = 10,
                    //    DelayInSeconds = 3,
                    //    UseIncrementalDelay = true,
                    //};
                    //options.HttpRequests.SharePointRest = new PnPCoreHttpRequestsSharePointRestOptions
                    //{
                    //    UseRetryAfterHeader = true,
                    //    MaxRetries = 10,
                    //    DelayInSeconds = 3,
                    //    UseIncrementalDelay = true,
                    //};

                    options.DefaultAuthenticationProvider = authenticationProvider;

                    options.Sites.Add("DemoSite",
                                      new PnP.Core.Services.Builder.Configuration.PnPCoreSiteOptions
                    {
                        SiteUrl = customSettings.DemoSiteUrl,
                        AuthenticationProvider = authenticationProvider
                    });
                });
            })
                       // Let the builder know we're running in a console
                       .UseConsoleLifetime()
                       // Add services to the container
                       .Build();

            await host.StartAsync();

            using (var scope = host.Services.CreateScope())
            {
                var pnpContextFactory = scope.ServiceProvider.GetRequiredService <IPnPContextFactory>();

                #region Interactive GET's
                using (var context = await pnpContextFactory.CreateAsync("DemoSite"))
                {
                    var accessToken = await context.AuthenticationProvider.GetAccessTokenAsync(context.Uri);

                    //Console.WriteLine($"Token: {accessToken}");
                    var CSOMContext = GetContext(context.Uri, accessToken);

                    using (CSOMContext) {
                        Web web = CSOMContext.Web;
                        CSOMContext.Load(web, w => w.Title, w => w.Description);
                        CSOMContext.ExecuteQuery();
                        Console.WriteLine(web.Title);
                    }
                }
                #endregion
            }

            host.Dispose();
        }