.Net Core Console Application for SharePoint Online using PNPCore library Interactive Login

Sathish Nadarajan
 
Solution Architect
October 16, 2021
 
Rate this article
 
Views
11653

In Many cases, we may need a Console application to do some sort of maintenance or any patch work to be done on the SharePoint Environment.

To connect with the SharePoint, we usually use the SharePointPNPCoreOnline Nuget package. But now, it is deprecated. Instead, we can use either PNP.Framework or PNP.Core.

PNP.Framework can be used from a .Net Framework application.

PNP.Core can be used from a .Net Core application.

In this application, let us see the steps to create the application step by step.

1. Open VS 2019 and create a new project.

 

2. Select the Framework as .Net 5.0

 

3. Open the NuGet Manager.

 

4. The below one is deprecated.

 

5. Install the PnP.Core

 

 

 

6. Install PnP.Core.Auth

 

 

7. After installing, the Program.cs will looks as below.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using PnP.Core.Services;

using System;
using System.Linq;
using System.Threading.Tasks;

namespace DotNet.Core.Console
{
class Program
{
public static async Task Main(string[] args)
{
var host = Host.CreateDefaultBuilder()

.ConfigureLogging((hostingContext, logging) =>
{
logging.AddEventSourceLogger();
logging.AddConsole();
})
.ConfigureServices((hostingContext, services) =>
{
// Read the custom configuration from the appsettings..json file
var customSettings = new CustomSettings();
hostingContext.Configuration.Bind("CustomSettings", customSettings);

// Add the PnP Core SDK services
services.AddPnPCore(options => {

options.PnPContext.GraphFirst = true;

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

});
});

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();

using (var context = await pnpContextFactory.CreateAsync("DemoSite"))
{
//Use the context to do the operations.

}
}

host.Dispose();
}
}
}

8. Appsettings.json will be as below.

{
"key": "generic",
"CustomSettings": {
"ClientId": "2ab1db09-3a59-48bc-*******-******",
"TenantId": "61943e96-b3a9-49dd-*****-*****",
"DemoSiteUrl": "https://sppalsmvp.sharepoint.com/sites/MySiteCollection/",
"DemoSubSiteUrl": "https://sppalsmvp.sharepoint.com/sites/MySiteCollection/",
"CredentialManager": "sppalsmvp",
"RedirectUri": "http://localhost",
"UserPrincipalName": "sathish@sppals.com",
"Password": "*****"
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}

9. Csproj as below

<Project Sdk="Microsoft.NET.Sdk">

 

<PropertyGroup>

<OutputType>Exe</OutputType>

<TargetFramework>net5.0</TargetFramework>

 

</PropertyGroup>

 

<ItemGroup>

<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />

<PackageReference Include="PnP.Core" Version="1.4.0" />

<PackageReference Include="PnP.Core.Auth" Version="1.4.0" />

</ItemGroup>

 

<ItemGroup>

<None Update="appsettings.json">

<CopyToOutputDirectory>Always</CopyToOutputDirectory>

</None>

</ItemGroup>

 

</Project>

 

10. When we execute this, the interactive login will be popped up.

 

With this, the .Net Core Console application is ready to work with SharePoint tenant.  We can do our activities with this PNPCoreContext object.

 

There are many other ways of authentication and getting the client context.  In this article, I have demonstrated the Interactive Login and the Client Credentials method.  In the upcoming articles, let us see how to get the context using user name and password, Azure Certificates etc.,

 

Happy Coding
Sathish Nadarajan

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

NodeJS – Get the List of Site Collections in my Office 365 Tenant by PNP JS Search Query

Sathish Nadarajan
 
Solution Architect
October 12, 2021
 
Rate this article
 
Views
519

In the earlier articles, we saw how to get the context of SharePoint from the Node application. As part of that, let us see, how to get the list of site collections in my office 365 tenant.

The Index.ts will be as below.

import express, { Application, ErrorRequestHandler, Request, response, Response } from 'express';
import NodeFetchClient from 'node-pnp-js';
import * as pnp from 'sp-pnp-js';

const app: Application = express();
const PORT = process.env.PORT || 2000;

let url = "https://sppalsmvp.sharepoint.com/sites/MySiteCollection/";
let credentialOptions = {
    username: 'sathish@sppals.com',
    password: '****'
};

app.get("/", async (req: Request, res: Response): Promise<void> => {


    pnp.setup({
        sp: {
            fetchClientFactory: () => {
                return new NodeFetchClient(credentialOptions, url);
            }
        }
    });

    pnp.sp.search({
        Querytext: "contentclass:STS_Site", SelectProperties: ["Title","SPWebUrl", "SPSiteUrl", "WebTemplate"], RowLimit: 500, TrimDuplicates: false
    }).then((r) => {

        r.PrimarySearchResults.forEach((value) => {
            console.log(`${value.Title} - ${value.SPWebUrl} - ${value.WebTemplate}`);
       });

        res.send('success');
        
    }).catch(e=>{
       res.status(500).send(e); 
    });

});

app.use(function (err: any, req: Request, res: Response, next: ErrorCallback) {
    res.status(err.status || 500);
    res.send(err);
});

app.listen(PORT, (): void => {
    console.log(`Server Running here https://localhost:${PORT}`);
});

Happy Coding
Sathish Nadarajan

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

NodeJS – Get SharePoint PnP-Core Client Context using UserName and Password and access SharePoint Objects from Node Application

Sathish Nadarajan
 
Solution Architect
October 11, 2021
 
Rate this article
 
Views
1000

In the earlier article, we saw how to setup a NodeJS application and start the development. As a continuation, let us see, how to create the SharePoint Context and access the SharePoint Sites.

The intention is to access the SharePoint objects and do some functionality from a Node JS application. i.e., a Separate standalone application which will do some action on our SharePoint Tenant.

To get the SharePoint Client Context, install the node-pnp-js and sp-pnp-js.

Let us take the earlier application itself for this continuation.

Install the following node modules.

npm install node-pnp-js –save
npm install sp-pnp-js –save
npm install pnp-auth –save
npm install @pnp/logging @pnp/common @pnp/odata @pnp/sp –save

Update the Index.ts file as below.

import express, { Application, ErrorRequestHandler, Request, response, Response } from 'express';
import NodeFetchClient from 'node-pnp-js';
import * as pnp from 'sp-pnp-js';


const app: Application = express();
const PORT = process.env.PORT || 2000;

let url = "https://sppalsmvp.sharepoint.com/sites/MySiteCollection/";
let credentialOptions = {
    username: 'sathish@sppals.com',
    password: '*******'
};

app.get("/", async (req: Request, res: Response): Promise<void> => {


    pnp.setup({
        sp: {
            fetchClientFactory: () => {
                return new NodeFetchClient(credentialOptions, url);
            }
        }
    });

    try {
        let list = await pnp.sp.web.lists.getByTitle('TempList').get();
        console.log(list);
        res.send(list);
    }
    catch (error) {
        res.send(error);
    }

});

app.use(function (err: any, req: Request, res: Response, next: ErrorCallback) {
    res.status(err.status || 500);
    res.send(err);
});

app.listen(PORT, (): void => {
    console.log(`Server Running here https://localhost:${PORT}`);
});

Then on the command prompt, execute npm run dev to run the server.

If we browse, then the output will be as below.

Download the Source HERE

Happy Coding
Sathish Nadarajan

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

Client Context is Coming as Null on the Host Web Remote Event Receivers in SharePoint Office 365

Sathish Nadarajan
 
Solution Architect
August 9, 2017
 
Rate this article
 
Views
5367

Many developers have faced this issue, whenever we deal with the remote event receiver. I have faced this long back and after sometime, again I was creating an event receiver, with the App Only Permission, then I again met with the same exception. – Client Context will be NULL.

As part of investigating this again, I found some interesting facts like, through fiddler logs, it says that “401 error” while trying to obtain the SharePoint client context. But, I Use the ClientContext Object, then immediately it throws, that “Object Reference not set to an instance”.

So, there is a mystery behind the authentication and the Remote Event Receivers in SharePoint. Basically, there are two types of Permissions, we would have seen. Both has the advantages and limitations on its own.

1. User + App Only token.

2. App Only token.

A Check box decides this on the App Manifest.xml

clip_image002

On the XML File, it will looks like,

clip_image004

For Our Event Receivers to work with the AppOnly Permission, the default code snippet generated by the Visual Studio will not work.

 public void ProcessOneWayEvent(SPRemoteEventProperties properties)
         {
             using (ClientContext clientContext = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
             {
                 if (clientContext != null)
                 {
                     clientContext.Load(clientContext.Web);
                     clientContext.ExecuteQuery();
                 }
             }
 
              
         }
 

Here on the above code, the ClientContext will always be null. Hence, we are not able to proceed. For this, there is a workaround. But eventually, the work around has is biggest draw back as well. But we can have a workaround for that also.

 public void ProcessOneWayEvent(SPRemoteEventProperties properties)
         {
             
             string webUrl = properties.ItemEventProperties.WebUrl;
 
             Uri webUri = new Uri(webUrl);
 
             string realm = TokenHelper.GetRealmFromTargetUrl(webUri);
             string accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, webUri.Authority, realm).AccessToken;
             using (var clientContext = TokenHelper.GetClientContextWithAccessToken(webUrl, accessToken))
             {
 // DO YOUR ACTION HERE.  A SAMPLE ACTION IS SHOWN BELOW.
                 clientContext.Load(clientContext.Web);
                 clientContext.ExecuteQuery();
 
                 string title = properties.ItemEventProperties.AfterProperties["Title"].ToString();
 
                 List lstDemoeventReceiver = clientContext.Web.Lists.GetByTitle(properties.ItemEventProperties.ListTitle);
                 ListItem itemDemoventReceiver = lstDemoeventReceiver.GetItemById(properties.ItemEventProperties.ListItemId);
 
                 itemDemoventReceiver["Column1"] = "Updated Value : " + title;
                 itemDemoventReceiver.Update();
                 clientContext.ExecuteQuery();
             }
         }
 

So, now the advantage is, with the AppOnly token, we are able to get the client context in the Remote Event Receiver.

In the same time, the disadvantage is, in the above piece of code, I am updating another column on the same list item. If you have a look on the screen, then the Modified By is coming as “SharePoint APP”. It should not be like that.

clip_image006

So, for this, we need to do a work around like, before updating the record, take the current user and then update that as well, wherever required. It is a simple work around, which we can easily do.

Happy Coding,

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

How to Get the Client Context Using App Access token, by passing Client ID and Client Secret ID using CSOM in SharePoint Office 365

Sathish Nadarajan
 
Solution Architect
November 20, 2016
 
Rate this article
 
Views
26287

In the recent articles, we saw how to get the ClientContext using the UserName and password. In this article, let us see how to create the ClientContext using any of the APP’s ClientID and ClientSecret ID. I know, this may not be necessary in all the scenarios. But let me explain the detailed scenario, why we required this also. That will help the readers to understand the requirement clearly.

We were working on a Migration Project, in which we need to continuously hit the Office 365 site in a very high frequency. At that time, the account which we are using for migration is being throttled by Microsoft. i.e., We cannot use the account for the next 10-20 mins. Hence, we were facing a lot of issues regarding this. (Planning to write a separate article for throttling. Let us see in the upcoming articles regarding the detailed throttling issues). In that case, we were trying with an APP model. i.e., Instead of using a service account, why cant we try with the Installed APP’s context.

With this background, hope we remember, how to create a PHA for Office 365. If not, please have a refresh HERE.

The important parameters to be noted are,

1. ClientID

2. ClientSecretID

3. RealmID

We can get the ClientID and ClientsecretID from the Web.Config of our APPs project.

And the Realm ID is nothing but the tenant ID. The tenant ID can be taken from the app principals.aspx.

https://*******.sharepoint.com/sites/developersite/_layouts/15/appprincipals.aspx

clip_image002

The piece of Code is as follows.

 namespace Console.Office365
 {
     using Microsoft.SharePoint.Client;
     using Newtonsoft.Json.Linq;
     using System;
     using System.Collections.Generic;
     using System.IO;
     using System.Linq;
 
     class Program
     {
         static void Main(string[] args)
         {
             CreateClientContextUsingClientIDandClientSecret();
         }
 
 
         public static void CreateClientContextUsingClientIDandClientSecret()
         {
             Uri webUri = new Uri("https://********.sharepoint.com/sites/developersite");
 
             var SharePointPrincipalId = "00000003-0000-0ff1-ce00-000000000000";
             var token = TokenHelper.GetAppOnlyAccessToken(SharePointPrincipalId, webUri.Authority, null).AccessToken;
 
             var ctx = TokenHelper.GetClientContextWithAccessToken(webUri.ToString(), token);
 
             Web web = ctx.Web;
             ctx.Load(web);
             ctx.Load(web.Lists);
             ctx.ExecuteQueryRetry();
         }
 }
 }
 

And on the APP.Config insert the below entries.

 <appSettings>
   <add key="ClientId" value="********" />
   <add key="ClientSecret" value="***************" />
   <add key="Realm" value="<<The one which we got from appprincipals.aspx>>" />
   </appSettings>
 

One important thing is, we should enable the APP Only Permission on the APP.

clip_image004

Hope this helps.

Happy Coding,

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

Deep Dive into SharePoint 2013 and JavaScript – Part 1

Ahamed Fazil Buhari
 
Senior Developer
August 12, 2016
 
Rate this article
 
Views
13085

Hello everyone, in this article we will see the relationship between SharePoint 2013 and JavaScript from scratch to end.

You might be an expert in SharePoint or expert in JavaScript but still some people have doubt that, what’s this JavaScript doing inside the SharePoint. If you have that doubt too, then you are at the right place to kick that doubt out of your head. I know that, it is too late to share about basic stuff related to SP 2013 in the year 2016, but still it’s worth sharing.

Ok let’s get into the business. Microsoft has promoted JavaScript to a first-class language with the release of SharePoint 2013, so that all SharePoint Developers must be comfortable.

In SP 2013, not only the App-Model changed the development landscape but additional capabilities across the product make the JavaScript an even more important skill for SharePoint developers.

Please make a note of these good practices and learn the below stuffs before you are writing JavaScript programming in SharePoint, definitely it will be helpful:

JavaScript namespace – In JavaScript, by default all the code loaded into the memory are tossed into a single big bucket called Global Namespace. Every variables, every functions and everything go inside the Global Namespace. There might be a chance we run into the risk of having conflicts between all of these names. If you are using jQuery, make use of jquery.noconflict() mode.

JSON – An Important element to understand is JSON (JavaScript Object Notation). JSON is a subset of the whole JavaScript object literal notation. In real-world, it is more on Data-Exchange. These are Key-Value pairs, separated by commas and wrapped in curly braces.

Promises in JavaScript – Promises are pretty advanced topic in JavaScript, but it facilitate clean code when you’re doing asynchronous programming like almost everything we do in SharePoint JavaScript. It allow to control over asynchronous call and related interactions. Some of the important functions in Promises are,

.then – Take action upon success/failure of a function.

.always – This always gets called, whether it was a success or failure.

.when – wait until all actions complete before performing another action (it is non-blocking operation and it supports both success and fail triggering).

To know more about Promise please refer here.

Strict Mode – If you’re using JavaScript and not using strict mode it’s harder to guarantee that things will end up where you want them to end up. Strict mode enforces a better flavor for JavaScript, this is option explicit mode from VB. It is easy to setting up Strict Mode, just add literal string “use strict” to your code. It can be entered at Library level or Function level. It prevents a lots of dumb mistake (for example: var abc = “1”; // strict mode

abc = “1” // not strict mode

JavaScript Development Tools

· Visual Studio Add-ons

o Web Essential 2012

o JavaScript Parser for Visual Studio (simple plugin used to find your way around large JavaScript files)

o JSLint for Visual Studio (code analysis for JavaScript).

· JSON Viewer

o https://jsonviewer.codeplex.com/

I am not explaining much on the above mentioned stuffs, because all those will lead to separate topic and it will divert from our main topic. So, I’m leaving it to the developers to learn by their own.

Out of the box SharePoint JavaScript environment:

1. SharePoint JavaScript

2. Variables

a. Context (ctx)

b. PageContext

3. Utilities

a. List Views

b. URL Manipulation

c. General Utilities

1. SharePoint JavaScript:

At a high level, SharePoint is just an ASP.Net web application like any other web application, it relies on client side scripting via JavaScript to deliver richer, more engaging user experiences. SharePoint has an extensive library of JavaScript used to deliver the experience we get out of the box. In the LAYOUTS directory there are around 170 JavaScript files.

The default SharePoint master page loads 5 js files (Core.js, Menu.js, Callout.js, Sharing.js, and SuiteLinks.js)

image

These files are loaded by using ScriptLink tag and using attribute OnDemand=”true”, so that these files are downloaded only if there’s a need.

Other common JavaScript libraries used across SharePoint include Init.js (more utility functions), SharePoint.js (main library for JavaScript Object Model – JSOM).

Many of the JavaScript files comes in SharePoint are in 2 flavors,

(*.js) Production and (*.debug.js) Debug.

Production – These files have the names what we would expect example: init.js, core.js etc and they are minified to reduce their size.

Debug – These have the same base name core, init, menu, whatever, but then debug.js instead of just .js so core.debug.js, menu.debug.js etc and these files that we want to work with if we need to debug.

2. Variables:

These variables represents an object that provides a lot of really useful information about the current context in which our code is running.

a. Context or ctx:

It provides wealth of information about the current page and the current environment. It won’t be available on all the pages, in general it’s not available on form pages (new, edit, display) and not available on layouts, site settings, administration pages etc. and also not available on apps unless we’re inside of a list. It is mainly available in Lists View pages.

image

v This variable is read-only and updating this variable has no effect. Some of the useful properties of the context (ctx) object includes

Ø List Data – gives us information about the items shown in the ListView web part on the current page. The data will be available only when we are viewing a list.

i. List View only

ii. Row collection property:

1. Column values

2. Row is 0-based, based on display, not item ID

3. ContentTypeId

4. FSObjType(0=ListItem, 1=Folder)

image

iii. Form URLs

1. displayFormURL

2. editFormURL

3. newFormURL

iv. ListTitle

v. ListURL

vi. ListGUID

vii. ListSchema

1. IsDocLib

2. Field Information

3. LocaleID

4. PagePath

viii. HttpRoot

1. BaseURL

ix. imagesPath

1. Relative Url to Images directory

It is good to make use of the Context (ctx) variable when there is only one ListView on the page.

b. _spPageContextInfo

It is pretty much similar to ctx variable and it is available on most of the pages like Layouts, site pages, apps etc. This provide access to lot of useful information, like current user, site, lists, pages etc.

Demo on SharePoint OOTB JavaScript Variables:

image

You can see lots of useful information available inside this ctx object, but I think that the most useful is if we need to go ahead and get the actual data values that are displayed inside the list view.

We do that inside the ListData Property, specifically inside the Row property of ListData. Each items are show inside this Row property in an array fashion.

document.location.href = SetUrlKeyValue("ID", "3", true, ctx.editFormUrl)

SetUrlKeyValue – This function allows us to specify the name or key value pair on the query string that we’re going to redirect the user.

In this example we want to specify the ID of 3, so that when we get the Edit form itself for that ID.

Here is the another example, with _spPageContextInfo variable

 var verUI;
 switch (_spPageContextInfo.webUIVersion) {
     case 12:
         verUI = "SharePoint 2007";
         break;
     case 14:
         verUI = "SharePoint 2010";
         break;
     case 15:
         verUI = "SharePoint 2013";
         break;
     default:
         verUI = "Unknown";
         break;
 }
 var msg = "Welcom to " + _spPageContextInfo.webTitle + ". You are browsing the site in " + _spPageContextInfo.currentCultureName + " using the " + verUI + " user interface";
 alert(msg);
 

Output:

image

3. Utilities – List View OOTB functions:

SelectAllItems, DeselectAllItems, CountSelectedItems(ctx), SelectRowByIndex(ctx,idx,addToSelection), GetListItemByID(ctx, id)

Selecting Items which has Odd Item ID.

 function selectItem() {
     clearAll();
     //Loop through each of the items using ctx.ListData.Row.length
     for (var i = 0; i < ctx.ListData.Row.length; i++) {
         //Selecting only odd ID number items
         if (parseInt(ctx.ListData.Row[i].ID) % 2 !== 0) {
             //Select that row using OOTB function
             SelectRowByIndex(ctx, i, true);
         }
     }
 }
 
 function clearAll() {
     var clvp = ctx.clvp;
     var tab = clvp.tab;
     //OOTB function to deselect the items
     DeselectAllItems(ctx, tab.rows, false);
 
 }
 
 //Function to show the Item tab in the ribbon
 function showItemTab() {
     ribbon = SP.Ribbon.PageManager.get_instance().get_ribbon();
     SelectRibbonTab("Ribbon.ListItem", true);
 }
 
 selectItem();
 var itemCount = CountSelectedItems(ctx);
 alert("There are " + itemCount + " selected items selected");
 showItemTab();
 

var itemCount = CountSelectedItems(ctx);

alert("There are " + itemCount + " selected items selected");

showItemTab();

image

SP.Utilities.Utility object (sp.js) –

Few examples:

alert(SP.Utilities.Utility.getLayoutsPageUrl("SiteSetting.aspx"));

To get the layout page:

image

To navigate within the modal dialog box:

<a onclick=’SP.Utilities.HttpUtility.navigateTo(“url”)’> click to navigate inside </a>

To know more about this utility function please refer to this msdn link. We end this Part 1 here

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

How to create a Provider Hosted Application on Form Based Authentication WebApplication in SharePoint 2013

Sathish Nadarajan
 
Solution Architect
June 8, 2015
 
Rate this article
 
Views
14722

In these previous articles, PHA and FBA, we saw how to create a Provider Hosted Application and How to make a Web Application as Form Based Authentication in SharePoint 2013. In this article, now, let us see how to integrate both of them. i.e., A Provider Hosted App which retrieves the Client Context of a SharePoint Web Application which is a Form Based Authentication using Visual Studio 2013.

One important thing we need to identify here is, there is a new class called SharePointContext.cs has been introduced by Microsoft with Visual Studio 2013, which is not there in Visual Studio 2012. Please find the reference here.

With that information, the rest of the steps are same as that of an ordinary Provider Hosted Application. Refer here

Everytime, I discuss about PHA, I am considering only the High Trust Apps. We had seen enough information about those in the past articles. Hence, I am targeting only, how to convert our AppWeb into Form Based Authentication, so that it can fetch the Client Context without any issues. Once, we fetch the client context, then the remaining things will be very smooth I guess.

To convert the Appweb as Form Based Authentication, there is nothing much. Only modifying the AppWeb’s web.config will do the magic. The sample web.config file is as follows. I request the readers to modify their web.config with appropriate values from their environment.

The sample web.config will be as below.

 <?xml version="1.0" encoding="utf-8"?>
 <!--
   For more information on how to configure your ASP.NET application, please visit
   http://go.microsoft.com/fwlink/?LinkId=169433
   -->
 <configuration>
   <system.web>
     <compilation debug="true" targetFramework="4.5" />
     <httpRuntime targetFramework="4.5" />
     <authorization>
       <deny users="?" />
     </authorization>
         <authentication mode="Forms" />
   </system.web>
   <appSettings>
     <add key="ClientId" value="7c6413ef-3c84-4f04-8912-b7b2c7e43ef9" />
     <add key="ClientSigningCertificatePath" value="C:SATHISHCertificatesPHACertificate.pfx" />
     <add key="ClientSigningCertificatePassword" value="Password11" />
     <add key="IssuerId" value="928a1244-8b2e-4d93-9e09-5c72445d15ca" />
   </appSettings>
   <system.serviceModel>
     <bindings>
       <basicHttpBinding>
         <!--Used by app for SharePoint-->
         <binding name="secureBinding">
           <security mode="Transport" />
         </binding>
       </basicHttpBinding>
     </bindings>
     <protocolMapping>
       <add binding="basicHttpBinding" scheme="https" bindingConfiguration="secureBinding" />
     </protocolMapping>
   </system.serviceModel>
     <system.webServer>
         <directoryBrowse enabled="true" />
     </system.webServer>
 </configuration>
 

Then on the Default.aspx.cs, let us try to get the ClientContext.

 protected void Page_Load(object sender, EventArgs e)
         {
             // The following code gets the client context and Title property by using TokenHelper.
             // To access other properties, the app may need to request permissions on the host web.
             var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
 
             using (var clientContext = spContext.CreateUserClientContextForSPHost())
             {
                 clientContext.Load(clientContext.Web);
                 clientContext.ExecuteQuery();
                 Response.Write(clientContext.Web.Title);
             }
         }
 

We can see a difference here. That is till Visual Studio 2012 Era, we used the TokenHelper.cs directly to get the ClientContext. But now in Visual Studio 2013, we can get the ClientContext by means of a new Class called SharePointContext.CS. I have mentioned a link earlier in this article, which describes about the SharePointContext.cs in detail.

Hope this is very easy right..

Download the Sample Config Files Here

Happy Coding,

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

Return Value from ClientContext.ExecuteQueryAsync in Javascript CSOM on SharePoint 2013

Sathish Nadarajan
 
Solution Architect
November 16, 2013
 
Rate this article
 
Views
42517

Most of the time, we would have been came across to fetch the list items using Javascript CSOM object model using SP.JS. Whenever we want to do some action, we can very well do that on the Success method. But I faced a different scenario, where I need to return the fetched list item to the parent method which is calling from an iFrame. Hence, the remaining process needs to be done from the iFrame. Not from our javascript method. Let the picture speaks more about this.

image

With the above scenario, the code would be something like,

 function GetRating(sender, args) {
 
                
         var ctx = new SP.ClientContext(“http://sathishserver:20000/sites/VHS/”);
         var web = ctx.get_web();
         this.list = web.get_lists().getByTitle(ListName);
         this.listItems = list.getItemsByID(ItemID);
 
         ctx.load(listItems, 'Include(ID, AverageRating)');
         ctx.executeQueryAsync(Function.createDelegate(this, GetRatingSuccess), Function.createDelegate(this, GetRatingFailure));
 
     }
 
 function GetRatingSuccess (sender, args) {
 
         RatingValue = listItems.itemAt(0).get_item("AverageRating");
         
 
     }
 
     function GetRatingFailure (sender, args) {
 
         alert(‘GetRating():' + args.get_message());
 
     }
 

Here, the GetRatingSuccess method is having the RatingValue. This value needs to be returned to the method within iFrame. I was trying with different options like Windows.Addlistener, attachevent, callback functions etc., but nothing had worked out. Since this is working with async thread, even the thread.sleep , settimeout, setinterval, nothing had worked out. At last, found an workaround. Instead of trying to return a value from this async function, call another method on the iFrame by passing this RatingValue as argument. This solves my requirement. J . The sample would be somewhat like

 function GetRatingSuccess (sender, args) {
 
         RatingValue = listItems.itemAt(0).get_item("AverageRating");
         
 document.getElementById("iFrameID").contentWindow.Success(RatingValue);
 
     }
 

The “Success” is the method which will be available on the iFrame.

This is very simple right. But to arrive this, spent a lot of time digging into the Callback and eventlisteners for async method. But I could say that, it is a quality time. J .

Hope this helps. Thanks.

Happy coding.

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

Leave a comment