Concept Of WebAPI And Registering Custom App Using Client ID And Client Secret

Introduction

 
We can split this article into 4 parts:
  1. Creating WebApi
  2. Registering custom App 
  3. Updating Author column using Csom
  4. Consuming WebApi

Creating WebApi

  • Open visual studio
  • Search for Asp.net web application
  • Enter project name,location ,soln name,and framework (.net framework 4.7.2) 
Concept Of WebAPI And Registering Custom App Using Client ID And Client Secret
  • Click create button 
  • Next, select empty project and check webapi tick mark in right corner
Concept Of WebAPI And Registering Custom App Using Client ID And Client Secret
  • Click create 
Add the following Nuget Pacakages,
  1. Microsoft.AspNet.WebApi.Cors
  2. SharePointPnPCoreOnline
  3. Newtonsoft.Json 
Right click controllers in the solution explorer -->Add-->Controller-->select WebAPI 2 Controller-empty and click add button give the name mynewcontroller.
 
Right click Models in the solution explorer -->Add-->New Item-->select Class and click add button give the name mycsom.cs.
 
Right click Models in the solution explorer -->Add-->New Item-->select Class and click add button give the name mymodel.cs
 
in MyNewController.cs,
  1. using Newtonsoft.Json;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5. using System.Net;  
  6. using System.Net.Http;  
  7. using System.Threading.Tasks;  
  8. using System.Web.Http;  
  9.   
  10. namespace WebApiwithSharepoint  
  11. {  
  12.     public class MyNewController : ApiController  
  13.     {  
  14.         public async Task SaveData(HttpRequestMessage value)  
  15.         //  public async Task SaveData([FromBody] List<arrayobj> paramsList)  
  16.         {  
  17.   
  18.             try  
  19.             {  
  20.                 string body = value.Content.ReadAsStringAsync().Result;  
  21.                 var datalayer = new mycsom();  
  22.                 mymodel dto = JsonConvert.DeserializeObject<mymodel>(body);  
  23.                 var setdata = datalayer.mysavedata(dto.Email);  
  24.             }  
  25.             catch (Exception ex)  
  26.             {  
  27.                 Console.WriteLine(ex.Message);  
  28.   
  29.             }  
  30.         }  
  31.     }  
  32. }  
In my model.cs,
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5.   
  6. namespace WebApiwithSharepoint  
  7. {  
  8.     public class mymodel  
  9.     {  
  10.         public string Email { getset; }  
  11.     }  
  12.  /*   public class arrayobj 
  13.     { 
  14.         public string Id1 { get; set; } 
  15.         public string Id2 { get; set; } 
  16.         public string Id3 { get; set; } 
  17.  
  18.     }*/  
  19. }  
 In mycsom.cs,
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Configuration;  
  4. using System.Linq;  
  5. using System.Threading.Tasks;  
  6. using System.Web;  
  7. using Microsoft.SharePoint.Client;  
  8. using SP = Microsoft.SharePoint.Client;  
  9.   
  10. namespace WebApiwithSharepoint  
  11. {  
  12.     public class mycsom  
  13.     {  
  14.         public async Task mysavedata(string value)  
  15.         {  
  16.   
  17.             try  
  18.             {  
  19.   
  20.                 string SPClientID = "clientid";  
  21.                 string SPClientSecret = "clientsecret";  
  22.                 string SitePath = "your site collection";  
  23.               /*  var clientid = ConfigurationManager.AppSettings["cid"]; 
  24.                 var clientsec = ConfigurationManager.AppSettings["csc"]; 
  25.                 var siteurl = ConfigurationManager.AppSettings["Spath"];*/  
  26.                 using (var clientContext = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(SitePath, SPClientID, SPClientSecret))  
  27.                 {  
  28.                     List oList = clientContext.Web.Lists.GetByTitle("Madhan");  
  29.                       ListItem item = oList.GetItemById(1); //here item ID updating a single item  
  30.                       clientContext.Load(item);  
  31.                     // item["Author"] = GetUsers(clientContext, "[email protected]");  
  32.                     item["Author"] = GetUsers(clientContext, value);  
  33.                     item.Update();  
  34.                         clientContext.ExecuteQuery();                
  35.                 }  
  36.   
  37.             }  
  38.             catch (Exception ex)  
  39.             {  
  40.   
  41.                 Console.WriteLine("Error Message: " + ex.Message);  
  42.             }  
  43.         }  
  44.         private static SP.FieldUserValue GetUsers(ClientContext clientContext, string UserName)  //Method for getting user id for given user mail
  45.         {  
  46.             SP.FieldUserValue userValue = new SP.FieldUserValue();  
  47.             SP.User updateUser = clientContext.Web.EnsureUser(UserName);  
  48.             clientContext.Load(updateUser);  
  49.             clientContext.ExecuteQuery();  
  50.             userValue.LookupId = updateUser.Id;  
  51.             return userValue;  
  52.         }  
  53.     }  
  54. }  
The below is the method for app context authentication:
  1. var clientContext = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(SitePath, SPClientID, SPClientSecret)   
In WebApiConfig.cs which is located in App_start folder:
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web.Http;  
  5. using System.Web.Http.Cors;  
  6.   
  7. namespace WebApiwithSharepoint  
  8. {  
  9.     public static class WebApiConfig  
  10.     {  
  11.         public static void Register(HttpConfiguration config)  
  12.         {  
  13.             // Web API configuration and services  
  14.             config.EnableCors(new EnableCorsAttribute("SiteCollectionurl""*""*"));  
  15.             // Web API routes  
  16.             config.MapHttpAttributeRoutes();  
  17.             config.Routes.MapHttpRoute(  
  18.                 name: "DefaultApi",  
  19.                 routeTemplate: "api/{controller}/{id}",  
  20.                 defaults: new { id = RouteParameter.Optional }  
  21.             );  
  22.         }  
  23.     }  
  24. }  
The below line used is for cross website requests,
  1. config.EnableCors(new EnableCorsAttribute("SiteCollectionurl""*""*"));  
In the sharepoint page it will execute Sharepoint operations using user context info, unfortunately it's a standalone application so we didn't get the context here. So to run the Sharepoint operation in csom either we need to provide credentials or client secret and the client id.
 
Here we are following the Sharepoint app concept to get context for running csom code. To register a new app you need to route to this url /_layouts/15/appregnew.aspx from your site collection.
 
Concept Of WebAPI And Registering Custom App Using Client ID And Client Secret
 
Navigate to that url and click the generate button. After copying the clientid and client secret in local notepad for future reference and clicking create once the app is created, we need to provide scope for that. Navigate to _layouts/15/appinv.aspx from your site collection,
 
Concept Of WebAPI And Registering Custom App Using Client ID And Client Secret
In this give the already-registered client id and click lookup, and it fetches all the details of the app. In the bottom of the page there is a textarea box for the scope of permision. Give the required permission in the form of xml format -- the permisions are here.
 
When you click on Create you'll be presented with a permission consent dialog. Press "Trust It" to grant the permissions,
 
Concept Of WebAPI And Registering Custom App Using Client ID And Client Secret
 
For details about app registration visit here.
 
This is purely run with app context so if you do any operations in Sharepoint list or library, the created and modified field is mapped as Shareppoint app instead of user name.  Provide the client id, client secret, site url in mycsom.cs file. Once completed bulid the solution. 
 
consuming webapi
  1. var urla = "https://localhost/api/MyNew/SaveData";  
  2. var data={ Email: "User Email" }  
  3. fetch(urla, {  
  4.     method : "POST",  
  5.     headers: {  
  6.       'Accept''application/json',  
  7.       'Content-Type''application/json'  
  8.     },  
  9.     //body: JSON.stringify([{"Id1":3,"Id2":76,"Id3":19},{"Id1":56,"Id2":87,"Id3":94},{"Id1":976,"Id2":345,"Id3":7554}])  
  10.      body: JSON.stringify(data)  
  11. }).then(  
  12.     response => response.text() // .json(), etc.  
  13.     // same as function(response) {return response.text();}  
  14. ).then(  
  15.     html => console.log(html)  
  16. );  
In Post Man or any RestApi clients,
 
Url
 
https://localhost/api/MyNew/SaveData
 
pre-request-script
  1. var body={  
  2.    Email:'Your Email'  
  3. }  
  4. pm.environment.set('req_body',JSON.stringify(body));  
Headers
 
Accept application/json
Content-Type application/json
 
Body
 
{{req_body}}
 

Conclusion

 
From this article we get some new idea of authenticating Sharepoint with the standalone progam, and also webapi process consumption in Sharepoint. I hope this helps someone. Happy Coding :)