Web Services

Ever always, whenever I come across this topic/question, I don’t have a very appropriate answer to it. So here I am summarizing my understanding of web services.

A Web service is a method of communication between two applications or electronic devices over the World Wide Web (WWW).

Two types to access web services: Simple Object Access Protocol (SOAP) and Representational State Transfer (REST).

Continue reading

Create basic SharePoint Add In using Angular 2

My last post concerns mainly to create a simple angular 2 application.

Now that we are well versed with it, our focus shifts as to how Angular 2 can be integrated with SharePoint. Let’s take a look into this one now.

Setting up the project for creating SharePoint Add In using Angular 2 in Visual Studio is quite confusing, hence I’m writing a detailed step by step description.

Also, point to be considered is, we will develop a SharePoint hosted Add In targeted for SharePoint 2013. The same may work for SharePoint Online, though I haven’t tried to explore it.

Creating Add In and removing unwanted files

Create a SharePoint Add In project in Visual Studio to be hosted as a SharePoint App targeted for SharePoint 2013.

The solution explorer has following files
setup1.jpg

Go to “Manage NuGet Package” and under the installed packages, remove the jQuery library.

This will remove all jQuery scripts from the Scripts folder.

setup2.jpg

Now, the Scripts folder should look like belowsetup3.jpg

Delete the app.js file from the Scripts folder.
setup4.jpg

tsconfig.json –

Add new item and search for the template json. Add the file – tsconfig.json

setup5.jpg

Add the below code to the file

{
  "compileOnSave": true,
  "compilerOptions": {
    "watch": true,
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "outDir": "./Scripts"
  },
  "exclude": [
    "node_modules"
  ]
}

Go to properties of tsconfig.json (F4)

Set Deployment type to NoDeployment

setup6.jpg

Other supporting libraries

Run the command prompt as administrator and traverse to the project folder.

Run the command – npm install angular2 systemjs es6-promise es6-shim rxjs

setup7.jpg

All packages will be placed under a folder named node_modules

The folder won’t be available in the solution explorer, however, upon clicking “View All Files”, the folder can be seen that is excluded from the project. Try not to include it as it will crash the VS.

setup1.jpg

To note – In a plain Angular2 app, the command used is npm install. It will generate all the libraries and place it inside the node_modules folder. However, this won’t work in a SharePoint Add In and may generate an empty folder. Hence, use the above mentioned command.

package.json – Having added the required libraries, let us move on to add this file – package.json.

  • Run command prompt as administrator
  • Traverse to the project folder
  • Run the command – “npm init”
    • The command prompt will ask few questions like the name, version, description, author, license, etc. Let all default values persist by just entering a name in lower case and entering blank for other values.
    • Confirm with a yes after furnishing all values.

setup1.jpg

A package.json file is created in the project, which is invisible in the solution explorer.

The same could have been created by the command – “npm init -y“. This would ensure that you don’t have to enter any default values and the package.json is created for you. However, once created, the name has to be changed to lower case, else it will show the red squiggly for error.

Show all files in solution explorer and right click on “Package.json”. Include it in project.

setup1.jpg

Go to properties of package.json (F4)

Set Deployment type to NoDeployment

setup1.jpg

App folder

  • Add a folder – app to the project
  • Add the component file
      • Add new item in the app folder
      • Search for the template TypeScript and create a file by the name – app.component.ts

setup1.jpg

  • import { Component } from 'angular2/core';
    @Component({
        selector: 'my-app',
        template: '
    <h1>My First SharePoint Add In using Angular2... Yoohoo!!!</h1>
    '
    })
    export class AppComponent { }
    

Write the above code and save the file. Saving the ts file generates a js file in the “Scripts” folder which won’t be visible.

Refresh the solution explorer and click “Show all files”, the js file will be visible in Scripts folder.

 

Before saving app.component.ts After saving app.component.ts
 setup1.jpg  setup1.jpg

Right click the js file in the Scripts folder and include in project.

Go to properties of app.component.ts (F4)

Set Deployment type to NoDeployment

  • Add the main/boot file

Add new typescript file in the app folder by the name – main.ts

import { bootstrap }    from 'angular2/platform/browser';

import { AppComponent } from './app.component';

bootstrap(AppComponent);

Write the above code and save the file. Saving the ts file generates a js file in the “Scripts” folder which won’t be visible.

Refresh the solution explorer and click “Show all files”, the js file will be visible in Scripts folder

Right click the js file in the Scripts folder and include it in project

Go to properties of main.ts (F4)

Set Deployment type to NoDeployment

So now, the solution explorer will look like

setup1

Note: You may encounter the following error while saving the ts files – “Project contained error. Output generation skipped”. However, the js files are generated, hence this error can be ignored.

Dependent Scripts

Add a new folder called NodeScripts to the project

Go to the below links right click and save each of the js files

Add these js files to the NodeScripts folder in the project

setup1.jpg

Web Page to host the application

Go to default.aspx page under Pages folder

Under PlaceHolderAdditionalPageHead, put the below content

<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">

    <meta name="WebPartPageExpansion" content="full" />

        <script src="../NodeScripts//es6-shim.min.js"></script>
        <script src="../NodeScripts/system-polyfills.js"></script>
        <script src="../NodeScripts/angular2-polyfills.js"></script>
        <script src="../NodeScripts/system.js"></script>
        <script src="../NodeScripts/Rx.js"></script>
        <script src="../NodeScripts/angular2.dev.js"></script>

        <script>
            System.config({
                packages: {
                    '../Scripts': {
                        format: 'register',
                        defaultExtension: 'js'
                    }
                }
            });
            System.import('../Scripts/main')
                  .then(null, console.error.bind(console));
        </script>
    </asp:Content>

Significance of above code

  • Shim and Pollyfills are used to support ECMA 6
  • System.js is used for
    • Using modules in JavaScript so that your JS doesn’t collide with others. Compartmentalize!
    • Load modules as they are needed and not all at once
  • Rx.js – Reactive extension to have “Promises” from JS for asynchronous calls.
  • Angular 2 library
  • System.config is used
    • To tell where the loader can find the scripts (here inside the Scripts folder)
    • To use scripts with extension “js”
  • System.import mentions the first file that is required to start the application. (here the file is main inside Scripts folder). It is equivalent to the main method.

Under PlaceHolderMain, put the selector

<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">

    <my-app></my-app>

</asp:Content>

Save the page

Now, the development is complete with all components and a let us do a quick check to ensure we are ready for deployment.

The deployment type is set to “NoDeployment for

  • all typescript files (.ts files inside app folder)
  • package.json and tsconfig.json

The js files for the respective ts files inside the Scripts folder are included in project.

Clean the solution and deploy

Opening the app will display the view that is created using Angular2.

setup1.jpg

Further typescript files can be added for any kind of logic and the respective JavaScript files can be deployed.

Create an angular 2 app from scratch

My previous post talks about the software requirements in order to create an angular 2 app. With all that in place, let us create our very first angular 2 app.

Create a folder for your project, say – AngularApp1.

Open Visual Studio Code and open your project folder. Now we are good to start adding files and work on our 1st Angular 2 app.

Add the following files in sequence

Continue reading

Software setup for angular 2 app

To create an angular 2 app, below are the pre-requisites.

NodeJS

  1. Check if NodeJs is installed in the machine
  2. Run command prompt as administrator
  3. Type “node –v”
    setup1
  4. This command gives the version if NodeJs is installed, else the command won’t be recognized.
  5. Download and install NodeJs from https://nodejs.org/en/ (latest), again check version.

IDE – Visual Studio Code

  1. Download and Install IDE – Visual Studio code from https://code.visualstudio.com/Download

Typescript

  1. Check if Typescript is installed
  2. Run the command prompt as administrator
  3. Type “tsc -v” 
    setup2
  4. This command gives the version if typescript is installed, else, the command won’t be recognized.
  5. Install typescript
    1. Run the command prompt as administrator
    2. Type “npm install –g typescript”
    3. Check version by running command tsc -v

Once all this is set up we are ready to code our first angular 2 app.

You can find step by step details of creating an angular 2 app in my next post… here

SharePoint event receiver getting triggered multiple times

Problem – Event receiver is getting fired twice.

My event receiver was supposed to send email to creator upon item added event. The event receiver was triggered, though it was sending two emails every time an item was created.

This was an indication that there were two event receivers attached to my list.

Solution – I followed the  below steps to troubleshoot

Continue reading

system.security.authentication.authenticationexception: the remote certificate is invalid according to the validation procedure.

Problem statement – While sending email using SMTP client using C# code, the following error comes up

system.security.authentication.authenticationexception: the remote certificate is invalid according to the validation procedure.

The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel

Solution – Add the code before calling smtpClient.Send(mail)

//Add following namespaces
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

smtpClient.EnableSsl = true;

ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };

Retrieve email id from a person or group field programatically

Requirement –  To retrieve email id of a user from a person or group field of a SharePoint list or library using C# code

Solution – Assuming that the query returns a list item collection

SPListItemCollection itemCollConfig = oConfigList.GetItems(oQuery);

if (itemCollConfig.Count &gt; 0)
{
     SPFieldUser userField = (SPFieldUser)itemCollConfig.Fields.GetField("HOD");
     //strHODEmail = Convert.ToString(itemCollConfig[0]["HOD"]);
     SPFieldUserValue userFieldValue = (SPFieldUserValue)userField.GetFieldValue(itemCollConfig[0]["HOD"].ToString());

      SPUser user = userFieldValue.User;
      strHODEmail = user.Email;
 }

First a reference is established to the field (field name – HOD in my case), and then the user value is retrieved from the particular index for that field.

Now remember, this would work when the person or group field is configured to accept only one value at a time.

If multiple users can be selected, then the class would vary slightly and collection will be used. Assuming item reference is available

string stEmails = string.empty;
SPFieldUser userField = (SPFieldUser)item.Fields.GetField("Users");
SPFieldUserValueCollection userFieldValueCollection = (SPFieldUserValueCollection)userField.GetFieldValue(item["Users"].ToString());
foreach (SPFieldUserValue userFieldValue in userFieldValueCollection)
{
strEmails = strEmails + userFieldValue.User.Email;
}

 

Next situation – When it is a people editor control on the page/web part, how to retrieve the user’s email. Below code would facilitate for the same. The people editor control here is “pplSendMail”

string strEmail = string.Empty;              
if (pplSendMail.ResolvedEntities.Count > 0)
{
    for (int i = 0; i < pplSendMail.ResolvedEntities.Count; i++)
    {
        PickerEntity user = (PickerEntity)pplSendMail.ResolvedEntities[i];
        SPUser webUser = SPContext.Current.Web.EnsureUser(user.Key);
        SPFieldUserValue value = new SPFieldUserValue(SPContext.Current.Web, webUser.ID, webUser.Name);
        strEmail = strEmail + "," + webUser.Email;
    }
}

Regex to validate email ids in InfoPath

Requirement – InfoPath form’s column should allow multiple valid email ids to be keyed in, separated by a comma.

InfoPath allows validation of an email id by default. It has a pattern to compare to. However, when the need arises to have multiple email ids inserted in a column, how to validate if all are valid email ids and are separated by a comma?

Solution – Write a validation rule for the column. The condition would be

Field: Email

Condition: does not match pattern

Custom pattern:  ([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\s*,\s*([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3}))*

Email