23
Jun
2017
ADFS Configuration in Windows Server 2012 R2 Standard with SharePoint 2013

The procedures in this article describe how to configure AD FS to act as an Identity Provider Security Token Service (IP-STS) for a SharePoint 2013 web application and Provider Hosted APP (SharePoint Add-In). In this configuration, AD FS issues SAML-based security tokens consisting of claims so that client computers can access web applications that use claims-based authentication. You can use an alternative identity provider than AD FS, but it must support the WS-Federation standard.Have a brief view on the major benefits of using AD FS in SharePoint solution:

  • Web single sign-on (SSO) – Federated Partners outside the organization can access organization’s Web-based applications, with Web SSO, an extensive feature of AD FS.
  • Partner user account management not required – Free from tiresome process of resetting and maintaining partner’s credentials. Also, if partnership terminates, the procedure can be performed with a single trust policy change.
  • AD FS Microsoft Management Console (MMC) – Core and centralized part of ADFS to perform management activities for Federal Partners.
  • Extensible architecture – This is more beneficial at times of claim processing. Claim processing and mapping comprises of adding and modifying claims by using business logics and AD FS trust policy.

Steps below present the technique to configure the Single Sign on between Provider Hosted App based on SharePoint Development on SharePoint Server.

(Prerequisite: SQL Server 2008/2012 must be installed.)

Follow below steps to configure ADFS:

    1. Click on “Add role and features” from server manager.
    2. In the respective wizard, select the options mentioned below and click on Next
      • Installation Type screen.
      • On Sever Selection screen, click on Select a server from the server pool
      • On Server Roles screen, click on Active Directory Certificates Services, Active Directory Domain Services and Active Directory Federation Services.
      • On Features screen, click on features based on requirements
      • Click on AD FS. Then further, Click on Next for AD CS
      • On Role Services screen, click on Certification Authority for Domain Certificate
      • AD DS screen will be available
      • On Confirmation screen, click on Install.

If all the above steps are sequentially performed, then it will successfully install. After installation, configure it as follows (Note: All services should be configured without an error as below & green colour showing configuration done successfully)

1

  1. On Server Manager Dashboard, Click on AD FS
  2. Click on More link display in yellow ribbon for Configuration AD FS

    2

  3. Click on Configure
  4. After clicking on Next follow the wizard sequentially and opt the options accordingly,
    • Select Create the first federation server in a federation server farm
    • Click on Change button to select user on Connect to AD DS screen.
    • On Specify Service Properties screen, select Domain Certificate from drop down list and enter Federation Service Name and Federation Service Display Name.
    • On Specify Service Account screen, select Use an existing domain user account or group managed service account. Here, mainly specify service configuration is done.

    After performing each step, Specify Service Account will be seen.

  5. On Specify Service Account screen, enter correct password in Account Password text box.
  6. Click on Next  On Specify Database screen, select Create a database on this server using Windows Internal Database
  7. Click on Next On Review options screen, you can view that the database is created successfully.
  8. Click on Next On Pre-requisite checks screen, check that pre-requisite is configured properly and click on Configure.
  9. To check its configured properly or not open below URL: https://<<FQDN>>/adfs/ls/IdpInitiatedSignon.aspx
  10. Enter valid credentials and click on Sign in button.

    3

  11. It will show Log Out screen.
  12. Click on Sign Out to sign out successfully.

After performing above mentioned, proceed ahead for provider hosted app creation.

Provider Hosted APP (SharePoint Add-In) Creation Demo

Registering APP in SharePoint Server and Hosting App in another Non-SharePoint Server. Follow below steps to register app:

Step 1

Create Register id from SharePoint 2013 site: –

  1. Open created developer site in browser
  2. Append _layouts/15/appregnew.aspx text in browser as below image
    4

  3. Click on Generate button of App Id (code will automatically generate in textbox)
  4. Click on Generate button App Secret (code will automatically generate in textbox)
  5. Please fill remaining field (here you can change your domain name)
  6. Click on OK button.
  7. All id will be displayed as below image
    5

  8. Copy all id and saved it notepad file. (This id will be changed in project’s web.config file)

Step 2

Need to create Provider Hosted App in Visual Studio 2012 or later. After creating it, publish the Provider hosted app then follow step 3 to host app in IIS and update app keys into the web.config file.

Step 3

Create web application in IIS

  1. Open run command and type inetmgr or open IIS
  2. Right click on sites and select Add website

    6

  3. Fill the form as below and click on OK button:

    7

ADFS Relying Party Demo – Provider Hosted APP

Configuration provider hosted app URL in ADFS allows to Single Sign On and pass the token from SharePoint Site. Follow below steps to configure ADFS for Provider Hosted APP Site which is in another non- SharePoint Server or Domain.

Follow below steps to relying party demo:

  1. Add relying party and click on Start
  2. On Select Data Source, select Enter data about the relying party manually
  3. By clicking on Next, follow the hierarchy of steps:
    • On Specify Display Name, enter Display Name
    • On Choose Profile select AD FS Profile. Click Next
    • On Configure URL tick on Enable support for the WS-Federation Passive protocol and enter Passive Protocol URL: (https://ProivderHostedURL/_trust/)

      8

    • Click Next On Configure Identifiers add URN

      9

    • On Configure Multi-Factor Authentication Now? Select I don’t want to configure multi-factor authentication settings for this replying party trust at this time.
    • On Choose Issuance Authorization Rules, select permit all users to access this replying party.
    • Click Next. It will automatically open Choose Rule Type On that in Claim Rule Template, select Send LDAP attributes as Claims
    • On Configure Claim Rule screen, add configure rules are mentioned below: Order requires to be as follows

      10

  4. Click Finish. It will automatically prompt the below screen. If not, right click on ADFS, and click on Properties. Click on Advance in Properties option and select SHA-1 search hash algorithm. Click OK

    11

Single Sign on Configuration for App and Server

Step 1 – Single Sign On Configuration for Server

It is a PowerShell Script to establish ADFS Server and SharePoint Server Connection. Below highlighted point will help SharePoint Server to communicate with on-premises Server (where ADFS is configured) which is in another Server or Domain and it will pass token to SharePoint Server to on-premises Server. Basically, this scenario called as Single Sign On Configuration. Open PowerShell command window and execute the below code:

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\Certs\Certificate.cer")
New-SPTrustedRootAuthority -Name "Token Signing Certificate ADFS Demo" -Certificate $cert
 
$emailClaimMap = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -IncomingClaimTypeDisplayName "EmailAddress" -SameAsIncoming
 
$roleClaimMap = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role" -IncomingClaimTypeDisplayName "Role" -SameAsIncoming
 
$upnClaimMap = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" -IncomingClaimTypeDisplayName "UPN" -SameAsIncoming
 
$realm = "urn:sharepoint:demo"
 
#Sign-in URL will be ADFS Server instance
$signInURL="https://abc. domain.com/adfs/ls"
 
#Create new trusted identity token issuer
$issuer = New-SPTrustedIdentityTokenIssuer -Name "ADFSDemo" -Description "ADFS Trusted Identity Provider Demo" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $emailClaimMap,$roleClaimMap,$upnClaimMap -SignInUrl $signInURL -IdentifierClaim $upnClaimMap.InputClaimType

(NOTE : The C:\Certs\Certificate.cer is the same certificate which is created in ADFS Relying Party for SharePoint Site in ADFS Server Step 14)
[ C:\Certs\Certificate.cer, urn:sharepoint:demo, https://abc. domain.com/adfs/ls, ADFSDemo and ADFS Trusted Identity Provider Demo need to be replaced based on user’s configuration. ]

Perform the below mentioned steps:

  1. Register SharePoint Site with URN in SharePoint Server:
    $t=Get-SPTrustedIdentityTokenIssuer "ADFSDemo" 
    $uri=new-object System.Uri("https://sp13-012:31418/_trust/") 
    $t.ProviderRealms.Add($uri, "urn:sharepoint:sharepointsite") 
    $t.Update()

    [sp13-012:31418 and urn:sharepoint:sharepointsite require to be replaced based on user’s configuration. ]

  2. Register Provider Hosted Site with URN in SharePoint Server:
    $t=Get-SPTrustedIdentityTokenIssuer "ADFSDemo" 
    $uri=new-object System.Uri("https://localhost:7443/_trust/") 
    $t.ProviderRealms.Add($uri, "urn:sharepoint:localhost ") 
    $t.Update()

    [localhost:7443 and urn:sharepoint:localhost require to be replaced based on user’s configuration. ]

  3. Go to central admin and select Trust Identity Provider:
    12

Get Client Context object for Provider Hosted APP in APP Part:

  1. Select APP Part and got to property or Press F4:
    13

  2. Add Custom Property as below in Provider Hosted Solution:
    14

  3. Add Property as follows:
    15

  4. Get user client context using below code:
    using (ClientContext clientContext = SharePointContextProvider.Current.GetSharePointContext(Context).CreateAppOnlyClientContextForSPHost())
    {
    List oList = clientContext.Web.Lists.GetByTitle("Contact");
    clientContext.Load(oList);
    clientContext.ExecuteQuery();
     
    If(Request.QueryString["UserName"] != null)
    {
    	string strUserEmail = Convert.ToString((Request.QueryString["UserName"]));
    strUserEmail += “@Domain.com// use domain
    ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
    Microsoft.SharePoint.Client.ListItem oListItem = oList.AddItem(itemCreateInfo);
     
    User user = clientContext.Web.EnsureUser(strUserEmail);
    clientContext.Load(user);
    clientContext.ExecuteQuery();
    Response.Write("
    " + user.LoginName + "
     
    "); oListItem["Title"] = "Test"; oListItem["Author"] = user; oListItem["Editor"] = user; oListItem.Update(); clientContext.ExecuteQuery(); } }
  5. Publish your project and add as web part and URL as follow:
    http://sharepointsite/pages/providerapppart.aspx?UserName=adminuser

Conclusion

AD FS being standards-based service allows the secure sharing of identity information between trusted business partners or federated partners across an extranet. In simple words, AD FS is an easy way out of remembering credentials and following multiple times same authentication steps to sign-on in the same web solution.

18
May
2017
SharePoint Provider hosted App with Single Page application with help of Angular JS 2

Environment Setup for Angular2 Development

Note: For this, Windows 2012 R2 OS machine for development is used. In which SharePoint 2013 server is also installed.

  1. Install node JS installer. Download the latest version of the installer file from here.
  2. Install Python 2.7. Download installer from the official website.
  3. Install Visual Studio 2015 with Update 3. You can also download setup from here.
  4. In may be a case where you may get the error during installation of Visual Studio. To resolve the error, you need to install required KB updates for Windows server 2012.
  5. Select Custom option and select only the below mentioned Features:
    1. Visual C++ (all options)
    2. Python tools for Visual Studio
    3. Microsoft Web Developer Tools
  6. Open Visual Studio 2015 From menu, click “Tools” click on “Options” under “Projects and Solutions”, select “External Web Tools”.
  7. Now arrange the locations of external tools. Create new path, if path is not existed click “OK” to save changes. Refer below image for this step.
    create path
  8. Install TypeScript_Dev14Fulll.exe to compile typescripts in Visual Studio. You can get appropriate version from here.
  9. Check whether SharePoint add-in templates are available in the Visual Studio or not. (From Create new project section, you can check if these templates are available or not.) If templates are not available in the Visual Studio, then download Microsoft Office Developer Tools Preview 2 installer from here.Install it for further steps and don’t forget to select SharePoint add-in templates option .
  10. Open command prompt and Run command to set path for Python 2.7: npm config set python python2.7
  11. Also, run another command: npm config set msvs_version 2015 –global

Configuration for SharePoint Provider hosted app

Follow Microsoft link to configure machine for SharePoint provider hosted app in on premise.

CRUD operations in list using SharePoint provider hosted app with Angular2

We are performing CRUD operations in the SharePoint Development where SharePoint list is residing in the host web. List name I have used static “TestAngular” with 2 fields Title, Number with single line column type.

  1. Create basic SharePoint Provider hosted app with MVC web application. Please follow Microsoft link.
  2. Open the appmanifest file of the SharePoint app from Solution explorer.
  3. Give “Manage” permissions on the site collection and list in appmanifest file.Give “Manage” permissions on the site collection and list in appmanifest file
  4. Create Web API controllers in MVC Web Application
    Use static list name “TestAngular”. Change the code in class file with name “WebApiConfig.cs” in the “App_Start” folder. This enables the session for the Web API. Replace existing code with below code in “WebApiConfig.cs” file.

    using System.Web;
    using System.Web.Http;
    using System.Web.Http.WebHost;
    using System.Web.Routing;
    using System.Web.SessionState;
    namespace PHA_MVCWeb.App_Start
    {
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                RouteTable.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                ).RouteHandler = new SessionRouteHandler();
     
                var json = config.Formatters.JsonFormatter;
                json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
                config.Formatters.Remove(config.Formatters.XmlFormatter);
            }
     
            public class SessionRouteHandler : IRouteHandler
            {
                IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
                {
                    return new SessionControllerHandler(requestContext.RouteData);
                }
            }
            public class SessionControllerHandler : HttpControllerHandler, IRequiresSessionState
            {
                public SessionControllerHandler(RouteData routeData)
                    : base(routeData)
                { }
            }
        }
    }
  5. Create new class file inside Filters folder with name “SharePointContextWebAPIFilterAttribute.cs”.
  6. Add below code inside “SharePointContextWebAPIFilterAttribute.cs” file.
    using System;
    using System.Net;
    using System.Net.Http;
    using System.Web;
    using ActionFilterAttribute = System.Web.Http.Filters.ActionFilterAttribute;
    namespace PHA_MVCWeb.Filters
    {
        public class SharePointContextWebAPIFilterAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
            {
                if (actionContext == null)
                {
                    throw new ArgumentNullException("actionContext");
                }
     
                Uri redirectUrl;
                switch (SharePointContextProvider.CheckRedirectionStatus(HttpContext.Current, out redirectUrl))
                {
                    case RedirectionStatus.Ok:
                        return;
                    case RedirectionStatus.ShouldRedirect:
                        var response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.Redirect);
                        response.Headers.Add("Location", redirectUrl.AbsoluteUri);
                        actionContext.Response = response;
                        break;
                    case RedirectionStatus.CanNotRedirect:
                        actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.MethodNotAllowed, "Context couldn't be created: access denied");
                        break;
                }
            }
        }
    }

    Notes (for above code):

    • System.Web.Http.Controllers.HttpActionContext doesn’t have HttpContext object associated, so use HttpContext.Current instead of OnActionExecuting when called CheckRedirectionStatus method from SharePointContextProvider class.
    • System.Web.Http.Controllers.HttpActionContext doesn’t have Result property, so use Response property to redirect and create Error response in the code.
  7. To create View Controller, create new Web API controller with name ViewController.cs inside the Controllers folder. This will retrieve all the items from the SharePoint list.
  8. Add below mentioned code in “ViewController.cs” file.
    using System.Collections.Generic;
    using System.Web.Http;
    using Microsoft.SharePoint.Client;
    using System.Web;
    using PHA_MVCWeb.Filters;
     
    namespace PHA_MVCWeb.Controllers
    {
     
        public class TestAngularModel
        {
            public string ID { get; set; }
            public string Title { get; set; }
            public string Number { get; set; }
     
            public TestAngularModel(string ID, string Title, string Number)
            {
                this.ID = ID;
                this.Title = Title;
                this.Number = Number;
            }
     
     
        }
     
        public class ViewController : ApiController
        {
            // GET api//5
            [SharePointContextWebAPIFilter]
            public List Get(int id)
            {
                List TestAngular = null;
                ListItemCollection itmCol = null;
                List itmList = new List();
     
                var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext.Current);
     
                using (var clientContext = spContext.CreateUserClientContextForSPHost())
                {
                    if (clientContext != null)
                    {
                        TestAngular = clientContext.Web.Lists.GetByTitle("TestAngular");
                        clientContext.Load(TestAngular);
                        clientContext.ExecuteQuery();
     
                        itmCol = TestAngular.GetItems(CamlQuery.CreateAllItemsQuery());
                        clientContext.Load(itmCol);
                        clientContext.ExecuteQuery();
     
                        foreach (ListItem itm in itmCol)
                        {
     
                            itmList.Add(new TestAngularModel(itm["ID"].ToString(), itm["Title"].ToString(), itm["Number"].ToString()));
                        }
     
                        return itmList;
                    }
                    else
                        return itmList;
                }
            }
        }
  9. To create Item Controller, create new Web API controller with name “CreateItemController.cs” in “Controllers” folder. It will create new item in the SharePoint list.
  10. Add below code to “CreateItemController.cs” file.
    using Microsoft.SharePoint.Client;
    using PHA_MVCWeb.Filters;
    using System.Web;
    using System.Web.Http;
     
    namespace PHA_MVCWeb.Controllers
    {
        public class CreateItemController : ApiController
        {
            [SharePointContextWebAPIFilter]
            public string Get(string name, string number)
            {
                List TestAngular = null;
     
                var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext.Current);
                using (var clientContext = spContext.CreateUserClientContextForSPHost())
                {
                    if (clientContext != null)
                    {
                        TestAngular = clientContext.Web.Lists.GetByTitle("TestAngular");
                        clientContext.Load(TestAngular);
                        clientContext.ExecuteQuery();
     
                        ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
                        ListItem oListItem = TestAngular.AddItem(itemCreateInfo);
                        oListItem["Title"] = name;
                        oListItem["Number"] = number;
     
                        oListItem.Update();
                        clientContext.ExecuteQuery();
     
                        return "Data saved!";
                    }
                    else
                    {
                        return "Error occurred!";
                    }
                }
            }
        }
    }

    Similarly create controllers for update and delete item.

  11. Create “NPM configuration file” with name “package.json” at root level.
  12. Add below code in the package.json file. It contains information about dependencies of angular package with versions for compiler. Here Angular 2 with RC6 is used.
    {
      "name": "aspnet",
      "version": "0.0.0",
      "scripts": {
        "postinstall": "typings install",
        "typings": "typings"
      },
      "license": "ISC",
      "devDependencies": {
       "concurrently": "^2.2.0",
        "lite-server": "^2.2.2",
        "systemjs-builder": "^0.15.16",
        "traceur": "^0.0.91",
        "typescript": "2.0.2",
        "typings":"^1.3.2"
      },
      "dependencies": {
        "@angular/common": "2.0.0-rc.6",
        "@angular/compiler": "2.0.0-rc.6",
        "@angular/core": "2.0.0-rc.6",
        "@angular/http": "2.0.0-rc.6",
        "@angular/platform-browser": "2.0.0-rc.6",
        "@angular/platform-browser-dynamic": "2.0.0-rc.6",
        "@angular/upgrade": "2.0.0-rc.6",
        "@angular/forms": "2.0.0-rc.6",
        "@angular/router": "3.0.0-rc.2",
     
        "core-js": "^2.4.1",
        "reflect-metadata": "^0.1.3",
        "rxjs": "5.0.0-beta.6",
        "systemjs": "^0.19.37",
        "typings": "^1.3.2",
        "zone.js": "^0.6.12",
        "moment": "^2.14.1"
      },
      "main": "systemjs.config.js",
      "author": "",
      "description": ""
    }
  13. Create “TypeScript JSON Configuration file” with name “tsconfig.json” at root level.
  14. Add below code in the “tsconfig.json” file.
    {
    {
      "compileOnSave": true,
      "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false
      },
      "exclude": [
        "node_modules",
        "node_modules/@types/jquery/index.d.ts",
        "typings/main",
        "typings/main.d.ts",
        "wwwroot",
        "Scripts/TypeLite.Net4.d.ts"
      ]
    }
  15. Create “JSON file” with name “typings.json” at root level.
  16. Add below code in “typings.json” file.
    {
      "ambientDependencies": {
        "bootstrap": "github:DefinitelyTyped/DefinitelyTyped/bootstrap/bootstrap.d.ts#56295f5058cac7ae458540423c50ac2dcf9fc711",
        "core-js": "registry:dt/core-js#0.0.0+20160317120654",
        "jquery": "github:DefinitelyTyped/DefinitelyTyped/jquery/jquery.d.ts#56295f5058cac7ae458540423c50ac2dcf9fc711",
        "TypeLite": "file:scripts/TypeLite.Net4.d.ts"
      }
    }
  17. Create “JavaScript” file with name “systemjs.config.js” at root level. This file loads all packages required for the application while initialization.
  18. Add below code in “systemjs.config.js” file.
    (function (global) {
        System.config({
            paths: {
                // paths serve as alias
                'npm:': '/node_modules/'
            },
            // map tells the System loader where to look for things
            map: {
                // our app is within the app folder
                app: 'app',
     
                // angular bundles
                '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
                '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
                '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
                '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
                '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
                '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
                '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
                '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
     
                // angular testing umd bundles
                '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
                '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
                '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
                '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
                '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
                '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
                '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
                '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
     
                // other libraries
                'rxjs': 'npm:rxjs',
                'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
            },
            // packages tells the System loader how to load when no filename and/or no extension
            packages: {
                app: {
                    main: './main.js',
                    defaultExtension: 'js'
                },
                rxjs: {
                    defaultExtension: 'js'
                },
                'angular2-in-memory-web-api': {
                    defaultExtension: 'js'
                }
            }
        });
    })(this);
  19. Create new “text” file with name “TypeLite.Net4.tt” in “Scripts” folder.
  20. Add below code in “TypeLite.Net4.tt” file.
    <#@ template debug="false" hostspecific="True" language="C#" #>
    <#@ assembly name="$(TargetDir)TypeLite.dll" #>
    <#@ assembly name="$(TargetDir)TypeLite.Net4.dll" #>
    <#@ assembly name="$(TargetDir)$(TargetFileName)" #>
     
    <#@ import namespace="TypeLite" #> 
    <#@ import namespace="TypeLite.Net4" #> 
    <#@output extension=".d.ts"#>
     
     <#@include file="Manager.ttinclude"#>
    <# var manager = Manager.Create(Host, GenerationEnvironment); #>
     
    <# var ts = TypeScript.Definitions()
    		.WithReference("Enums.ts")
    		.For<Models.List>()
    		.For<Models.ViewModel.JSONReturnVM<object>>();
    #>
     
    <#= ts.Generate(TsGeneratorOutput.Properties) #>
     
    <# manager.StartNewFile("Enums.ts"); #>
    <#= ts.Generate(TsGeneratorOutput.Enums) #>
    <# manager.EndBlock(); #>
    <# manager.Process(true); #>
  21. To create root – APP module for Angular2 application, create “app” folder at root level of web application.
  22. Create new “typescript” file with name “main.ts” inside “app” folder. This file will load first and load the AppModule.
  23. Add below code in “main.ts” file.
    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    import { AppModule } from './app.module';
    platformBrowserDynamic().bootstrapModule(AppModule);
  24. Create new typescript file with name “app.module.ts” inside “app” folder. Main.ts file will load this file first while initialization of application. The file defines modules that are used in application.
  25. Add below code in “app.module.ts” file.
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { Route, RouterModule } from '@angular/router';
    import { HttpModule } from '@angular/http';
    import { FormsModule } from '@angular/forms';
    import { routing } from './app.routes';
    import { AppComponent } from './app.component';
    import { ViewComponent } from './viewComponent/view.component';
     
    @NgModule({
        imports: [BrowserModule, HttpModule, RouterModule, FormsModule, routing],
        declarations: [AppComponent, ViewComponent],
        bootstrap: [AppComponent]
    })
    export class AppModule { }
  26. Create new “typescript” file with name “app.component.ts” in “app” folder. The file will load content for first page.
  27. Add below code in “app.component.ts” file.
    import { Component,} from '@angular/core';
    import { Http, Response, Headers, RequestMethod, HttpModule, RequestOptions, Request } from '@angular/http';
    import { FormsModule } from '@angular/forms';
    import { ViewDataService } from './services/viewData.service';
     
    @Component({
        moduleId: module.id,
        selector: 'app-work',
        providers: [ViewDataService],
        templateUrl: 'app.component.html'
    })
     
    export class AppComponent {
    }
  28. Create new “html” file with name “app.component.html” in “app” folder. The file contains html part of first page.
  29. Add below code in “app.component.html” file.
    <div class="row">
    <div class="col-md-12">
    <h2>CRUD Operations using Angular2!</h2>
    <hr />
    </div>
    </div>
    <div class="clearfix"></div>
    <div class="row">
    <div class="col-sm-3">
    <div class="sidebar-nav">
    <div class="navbar-collapse collapse sidebar-navbar-collapse">
    <ul class="nav navbar-nav">
    	<li><a routerlinkactive="active" routerlink="/viewcomponent" routerlinkactiveoptions="" exact:="" true="">View all items</a></li>
    	<li><a routerlinkactive="active" routerlink="/createitem">Create new item</a></li>
    	<li><a routerlinkactive="active" routerlink="/updatecomponent">Update item</a></li>
    	<li><a routerlinkactive="active" routerlink="/deletecomponent" href="#">Delete item</a></li>
    </ul>
    </div>
    </div>
    </div>
    <div class="col-md-9">
            <router-outlet></router-outlet>
    </div>
    </div>
  30. To create viewData.service.ts ,create new folder with name “services” in “app” folder.
  31. Create new “typescript” file with name “viewData.service.ts” in “services” folder. It will access Web API “viewController” which is created before.
  32. Add below code in “viewData.service.ts” file.Note: Here static url is used for demo purpose.
    import { Injectable } from '@angular/core';
    import { Http, Response, Headers, RequestMethod, HttpModule, RequestOptions, Request } from '@angular/http';
     
    @Injectable()
    export class ViewDataService {
     
        constructor(private _http: Http) {
        }
     
        viewData() {
            let listUrl = `https://localhost/api/view/1?SPHostUrl=https%3A%2F%2Ftatvasoft607%2Esharepoint%2Ecom%2Fsites%2FProviderApp&amp;SPLanguage=en-US&amp;SPClientTag=0&amp;SPProductNumber=16%2E0%2E6406%2E1200&amp;SPAppWebUrl=https%3A%2F%2FTatvasoft607-69192fd3dcf4a6%2Esharepoint%2Ecom%2Fsites%2FProviderApp%2FPHA_MVC`;
     
            let reqOptions = new RequestOptions({
                url: listUrl,
                method: RequestMethod.Get,
                headers: new Headers({ accept: 'application/json; odata=verbose', 'content-type': 'application/json; odata=verbose' }),
                body: null
            });
            let req = new Request(reqOptions)
            return this._http.request(req).map((res) =&gt; {
                return res.json()
            });
        }
    }
  33. To createData.service.ts, create new “typescript” file with name “createData.service.ts” in “services” folder. It will access Web API “CreateItemController” which is created before.
  34. Add below code “createData.service.ts” file.Note: Here the static url is used for demo purpose.
    import { Injectable } from '@angular/core';
    import { Http, Response, Headers, RequestMethod, HttpModule, RequestOptions, Request } from '@angular/http';
     
    @Injectable()
    export class CreateItemService {
     
        constructor(private _http: Http) {
        }
     
        updateItem(id: string, title: string, number: string) {
            let listUrl = `https://localhost/api/createitem? name=${title}&amp;number=${number}&amp;SPHostUrl=https%3A%2F%2Ftatvasoft607%2Esharepoint%2Ecom%2Fsites%2FProviderApp&amp;SPLanguage=en-US&amp;SPClientTag=0&amp;SPProductNumber=16%2E0%2E6406%2E1200&amp;SPAppWebUrl=https%3A%2F%2FTatvasoft607-69192fd3dcf4a6%2Esharepoint%2Ecom%2Fsites%2FProviderApp%2FPHA_MVC`;
     
            let reqOptions = new RequestOptions({
                url: listUrl,
                method: RequestMethod.Get,
                headers: new Headers({ accept: 'application/json; odata=verbose', 'content-type': 'application/json; odata=verbose' }),
                body: null
            });
            let req = new Request(reqOptions)
            return this._http.request(req).map((res) =&gt; {
                return res.json()
            });
        }
    }

    This way you can create services for update and delete operations.

  35. To create ViewComponent, create new folder with name “viewComponent” in “app” folder.
  36. Create new “typescript” file with name “view.component.ts” in “viewComponent” folder.
  37. Add below code in “view.component.ts” file.
     
    import { Component, OnInit, Input } from '@angular/core';
    import { ViewDataService } from '../services/viewData.service';
     
    @Component({
        selector: 'view-item',
        providers: [ViewDataService],
        template: `
    <table class="table table-bordered">
    <thead>
    <tr>
    <th>Name</th>
    <th>Number</th>
    </tr>
    </thead>
     
     
    <tbody>
    <tr ngfor="let frnd of results;">
    <td>{{frnd.Title}} {{last}}</td>
    <td>{{frnd.Number}}</td>
    </tr>
    </tbody>
     
    </table>
     
    `
    })
    export class ViewComponent implements OnInit {
     
        results: Array<object>;
     
        constructor(private _viewDataService: ViewDataService) {
        }
     
        ngOnInit() {
     
            this._viewDataService.viewData().subscribe(data =&gt; this.results = data);
     
        }
    }
    </object>
  38. Open “index.cshtml” from “Views” folder. Here all required JavaScript libraries are attached as per hierarchy.
  39. Replace existing code of “index.cshtml” file with below one.
    @{
        ViewBag.Title = "Home Page";
    }
    <!-- 1. Include JS libraries -->
    <!-- 2. Configure SystemJS -->
        System.import('app/main');
        System.import('app').catch(function (err) { console.error(err); });
    <base href="/" />
    <div class="jumbotron">
        <app-work>Loading...</app-work>
    </div>
    <div class="row">
    </div>
  40. To create Item Component, create new folder with name “CreateItemComponent” in “app” folder.
  41. Create new “typescript” file with name “createItem.component.ts” in “CreateItemComponent” folder.
  42. Add below code in “createItemModule.ts” file.
     
    export class createItemModule {
        constructor(public name: string, public number: string) { }
    }
  43. Create new “typescript” file with name “createItem.component.ts” in “CreateItemComponent” folder.
  44. Add below code in “createItem.component.ts” file.
     
    import { Component } from '@angular/core';
    import { Http, Response, Headers, RequestMethod, HttpModule, RequestOptions, Request } from '@angular/http';
    import { FormsModule } from '@angular/forms';
    import { createItemModule } from './createItemModule';
    import { Router } from '@angular/router';
    import 'rxjs/add/operator/share';
    import 'rxjs/add/operator/map';
    import 'rxjs/Rx';
     
    @Component({
        moduleId: module.id,
        selector: 'create-item',
        providers: [CreateDataService],
        templateUrl: 'create.item.html',
        styles: ['.ng-valid[required], .ng-valid.required  {border-left: 5px solid #42A948; /* green */} .ng-invalid:not(form)  {border-left: 5px solid #a94442; /* red */} .h3Title{margin-top:0px;}']
    })
     
    export class CreateItemComponent {
     
        model = new createItemModule('', '');
     
        constructor(private _http: Http, private _router: Router, private _createDataService: CreateDataService) {
        }
     
        submitForm(form: any): void {
     
             this._ createDataService.createItem(form.name, form.number).subscribe(data =&gt; alert(data));
     
            this._router.navigateByUrl('/viewcomponent');
        }
    }
  45. Create new “html” file with name “create.item.html” inside “CreateItemComponent” folder.
  46. Add below code in “create.item.html” file.
     
    <h3 class="h3Title">Create new item</h3>
    <form form="ngForm" novalidate="">
    <div class="form-group">
            <label for="name">Name:</label>
            <input type="text" class="form-control" id="name" required="" ngmodel="" model="" name="" name="name" name="ngModel" />
    <div hidden="" name="" valid="" name="" pristine="" class="alert alert-danger">
              Name is required.
    </div>
    </div>
    <div class="form-group">
            <label for="number">Number:</label>
            <input type="text" class="form-control" id="number" required="" ngmodel="" model="" number="" maxlength="5" pattern="[1-9][0-9]{4}" name="number" number="ngModel" />
    <div hidden="" number="" valid="" number="" pristine="" class="alert alert-danger">
                Number is required. <i>Maxlength = 5 and first letter should be non-zero.</i>
    </div>
    </div>
        <button type="button" click="" submitform="" form="" value="" disabled="disabled" form="" form="" valid="" class="btn btn-default">Submit</button>
    </form>

    This way you can create components for update and delete operation.

  47. To implement routing Angular2 and to create Single Page Application, create new typescript file with name “app.routes.ts” in “app” folder. It will route components in angular application.
  48. Add the below code in the “app.routes.ts” file.
     
    import { Routes, RouterModule, provideRoutes } from '@angular/router';
    import { AppComponent } from './app.component';
    import { ViewComponent } from './viewComponent/view.component';
    import { CreateItem } from './createItem/create.item';
    import { DeleteComponent } from './deleteComponent/delete.component';
    import { UpdateComponent } from './updateComponent/update.component';
     
    export const routes: Routes = [
        { path: 'viewcomponent', component: ViewComponent },
        { path: '', redirectTo: '/viewcomponent', pathMatch: 'full' },
        { path: 'createitem', component: CreateItem },
        { path: 'updatecomponent', component: UpdateComponent },
        { path: 'deletecomponent', component: DeleteComponent }
    ];
    export const routing = RouterModule.forRoot(routes);
  49. Build the solution and publish the SharePoint app. Publish the web application.
  50. Right click on web application project click on “Open Folder in File Explorer”.
  51. File Explorer window will be opened. Find and copy the folder “node_modules” paste the folder in the published folder. We need to add this “node_modules” folder with the published code files in the hosting environment. As this folder contains all the typescript and JavaScript files dependencies.
  52. Output

    CRUD Operation using Angular 2
    CRUD Operation using Angular 2