Office 365 addins as microservices on Docker containers

Office 365 Addins on Docker

This example shows how to run office 365 addins as microservices on Docker containers

watch this video to see this in action

Below sections would be covered in this sample

  1. Why Docker?
  2. Prerequisites
  3. Configure Docker
  4. Docker Components
  5. Docker Commands
  6. Build NodeJS Base Image
  7. Build Office 365 NodeJS Microservice
  8. Dockerize Office365 Microservice
  9. Publish Microservice to Azure Docker Container
  10. How to run this sample

1. Why Docker?

  • Docker is an exciting new technology to build platform agnostic light weight apps/micro services/containers which can be provisioned, deployed, scaled faster than traditional VM’s.
  • Building Cloud hosted/provider hosted SharePoint/Office365 addins requires additional infrastructure to the mix.
  • Docker’s X-Plat CLI tools to provide continous integration and delivery thus making DevOps relatively simpler.
    For more details read docker docs

2. Prerequisites

  1. Windows 7 or Above
  2. Office 365 subscription
  3. Azure subscription
  4. Visual Studio Code

3. Configure Docker

  1. Install docker tool kit from docker docs
  2. Run docker quick start terminal
  3. To run this sample straightaway skip to “10. How to run this sample”.

4. Docker Components

  1. Docker Images > Blueprints of our application
  2. Docker Container > Created from docker images and are real instances of our application
  3. Docker Daemon > Building, running and distributing Docker containers
  4. Docker Client > Run on our local machine and connect to the daemon
  5. Docker Hub > A registry of docker images

5. Docker Commands

  1. $docker build
  2. $docker run
  3. $docker search
  4. $docker ps
  5. $docker images
  6. $docker rmi
  7. $docker pull
  8. $docker push
  9. $docker-machine env
  10. $docker-machine create
  11. $docker attach

6. Build NodeJS Base Image

FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y nodejs nodejs-legacy npm
RUN apt-get clean

7. Build Office 365 NodeJS Microservice

Run the sample Office 365 Add in from your local machine following this article

8. Dockerize Office365 addin

  • First install the required packages from package.json
COPY ./package.json src/
RUN cd src && npm install
  • Then copy all the source code
COPY . /src
  • Set working directory for docker daemon
  • Set default comment on start
CMD ["npm","start"]
  • Now build the Docker Image and Run it
docker build -t o365addin-docker:0.1 .
docker run -d -p 80:3000 o365addin-docker:0.1
  • Change the AppID and Redirection URL’s in Azure and authHelper.js

  • Test the app in browser

9. Publish Microservice to Azure

1) Create SSL certs using Open SSL

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout o365-docker.pem -out o365-docker.pem
openssl x509 -inform pem -in o365-docker.pem -outform der -out o365-docker.cer
openssl pkcs12 -export -out o365-docker.pfx -in o365-docker.pem -name "o365-docker Certificate"

2) Upload o365-docker.pem to Azure -> Settings -> Management Certificates -> Upload

3) Now Create a docker Microservice in Azure

docker-machine create -d azure --azure-subscription-id="d48ccdca-d4ab-4579-89fa-ed113033bf74" --azure-subscription-cert="o365-docker.pem" --azure-location="East US" o365ondocker

4) Connect to Azure Docker machine

eval "$(C:/Program\ Files/Docker\ Toolbox/docker-machine.exe env o365ondocker)"

5) Change the AppID and Redirection URL’s in Azure and authHelper.js

6) Build and Run the app

docker build -t o365addin-docker:0.1 .
docker run -d -p 80:3000 o365addin-docker:0.1

7) Test the app in browser

10. How to run this sample

1) Open Docker quick start terminal
2) Clone this repo

git clone

3) Update Office 365 App permissions and authhelper.js with Docker IP

docker-machine ip default

4) Build the docker image

docker build -t o365addin-docker:0.1 .

5) Run the docker container

docker run -d -p 80:3000 o365addin-docker:0.1

demystifying User Profile picture sync in #Office365

User profile pictures is one of the key factor for collaboration with in Office365. User Pictures are surfaced on almost of the service with in Office 365 such as Exchange Online, SharePoint Online, Lync (Skype) Online as well their client applications such as Outlook, Office, Skype for business etc.

To provide seamless experience to the end users its important to understand how it pictures are synchronized internally with in Office 365, Some notable issues and possible ways of automation.

Typical User Profile Sync process:

Most common scenario is of user profile picture sync process is through DirSync. When Dirsync completes the Synchronization to Azure AD, EXO gets a copy from AzureAD then SPO gets a copy from EXO. Though Outlook/Lync online is updated instantly, SPO might take up to 72 hours to show the picture.  EXO uses single image throughout the application. But SPO online uses three different images of single single user profile. For an example SPO ribbon uses a small image where as MySite/Delve uses a larger image.  So the User profile Service takes extra time to scale the images.

SPO Image variations:
200px * 200 px

72px * 72px

48px * 48px


Its not always a smooth ride from DirSync to SPO. If the process fails at any of the three stages, user’s may not get a profile pic in SPO. Here are some of the scenarios

  • AD images greater than 10KB or with wrong dimensions
  • Licensed for SPO but not EXO
  • Poor picture resolution in SPO Delve/Mysites


I often faced scenarios where the customers would require their pics across all the services in Office 365 in the next day. In those cases PowerShell is your friend. Below script uses Set-UserPhoto to upload high resolution pictures to EXO and ProfilePictureUploader project from Office365 Developer Patterns and Practices (PNP) to upload the Profile pictures to SharePoint Online.


Now the only thing you needed is the high resolution images on your local file share in “Firstname Lastname.JPG” format and configure the variables. This script

  • Saves the credentials securely for future use
  • Generates the UPN values from the User profile picture names. (Eg: John Doe.jpg =>
  • Uploads the image to Exchange online
  • Scales the source image small (48px), medium (72px), Large (200 PX) images and uploads to SharePoint online
  • Archive the processed images

How to run this:

Download the Zip file and Configure the below values in configuration.xml

Configuration values:

For details please refer ProfilePictureUploader project

  1. tenantName: eg:
  2. pictureSourceCsv: C:\Scripts\UpdateProfilePics\Release\userlist.csv
  3. thumbs upload3Thumbs: True
  4. additionalProfileProperties:
  5. logFile path:“C:\Scripts\UpdateProfilePics\Release\log.txt”
  6. uploadDelay:500
  7. credFile:Location to store the O365 credentials
  8. psLogfile: Location to store PS logs
  9. (Global admin)
  10. localPhotosFolder:\\fs.corp.local\Public\Employee Photos\O365\ready
  11. localPhotosArchiveFolder:\\fs.corp.local\Public\Employee Photos\O365\archive
  12. domainName:spbreed
  13. exeLocation:C:\Scripts\UpdateProfilePics\Release (Location of ProfilePictureUploader Binaries)

Troubleshooting tips:

  •  O365AdminAccount should be a Office 365 global administrator
  • SetExecutionPolicy RemoteSigned should be enabled
  • Powershell modules for Azure AD and MSOL Sign in assistant should be installed.


AutoSPInstaller with #SP2016 on #Win2016 and #SQL2016

Since the release AutoSPInstaller by Brain Lalancette in 2010 , I am an ardent fan of this tool and used it in every other SharePoint deployment.

Not surprisingly AutoSPInstaller for SharePoint 2016 is out immediately after few days of #SP2016 Preview release.

Recently AutoSPinstaller online is release as well to generate the farm configuration file to run this tool.

For more details refer

Recently I had a chance to install SP2016 on Win2016 and SQL 2016. AutoSpInstaller worked fine without any glitch and I was able to configure a single server farm in 4-5 hrs on Azure.

Here are the steps:

  1. Launch a VM using Win Server 2016 Technical preview 3 base image or install it on a Local VM2016_image_select
  2. Provision E:\ and F:\ for SQL and Logs
  3. Join the server to a domain
  4. Fully functional SharePoint install requires atleast 9 service accounts. Below PowerShell script can be used to automate Service account creation and to configure “No password expiry” policies. Update the CSV file with required values: Create-ADUsers.ps1
  5. Add replicating directory changes permission to spprofilesync account
  6. Though SharePoint adds required firewall ports during setup, I used the below scripts to add required firewall ports in advance
    1. Create-FWRulesDB.ps1
    2. Create-FWRulesWFE.ps1
  7. Download and Install SQL server 2016 preview from Use SQLService accounts created in step 3 while configuring SQL services
  8. Pre configure app domain using
  9. Download AutoSPSourcebuilder from and unzip in the same drive
  10. Download AutoSPInstaller from and unzip in the same drive 
  11. Download #SP2016 preview from and mount it as 

    MOUNT-DISKIMAGE C:\ISO\SharePoint Server 2016 IT Preview.ISO

  12. Now navigate to AutoSPSourceBuilder  and run PS F:\AutoSPSourceBuilder> .\AutoSPSourceBuilder.ps1 -GetPrerequisites:$true  -Destination “F:\AutoSPInstaller\SP\2016”   to create SlipStreamed version of #SP2016


  13. Now prepare AutoSPInstallerInput.xml for SharePoint 2016. Its highly recommended use  to generate this config today. But as of today (09/03/2016) online    tool to generate config file for SP2016 is not supported. Only notable difference wrt to AutoSPInstaller between #SP2013 and #SP2016 is the introduction MinRoles to simplify the deployment and scaling. For more details refer
  14. Select <SingleServerFarm Provision=”true” /> for single server farm setup. Attached is the sample Config file for SP2016 for your reference. AutoSpInstallerInput.xml minroles
  15. Now run the .\AutoSPInstallerLaunch.bat. Installation will be a breeze.


Jumpstart AngularJS app development for O365 & E2E testing using Protractor

BDD (Behaviour Driven Development) and TDD ( Test Driven Development) has become cornerstone for modern Javascript app development but adopting these development strategies to SharePoint/Office 365 is not a trivial task.

I was intrigued to discover #Protractor, an AngularJS testing framework. With client side MVC/MVVM frameworks getting popular among the developers, AngularJS is the premier framework to develop Office365/SharePoint 2013 apps. Integrating TDD methodologies to app development model will help developers to deliver maintainable, flexible and extensible solutions and interfaces.

Below is the RevealJS presentation on how to create AngularJS based SharePoint app and execute end to end testing using #Protractor. I would like to thank Andrew Connell for introducing  RevealJS and AngularJS Apps

This presentation includes training videos and Source code to build SharePoint
1) Expenses AngularApp(SharePoint hosted App)
2) ExpensesAngularApp test (NodeJS project created using VS2013)
1. Expenses AngularApp:
– This is a SharePoint hosted app developed using popular angular framework.
– Utilizes best patterns and practises for angular framework based on HotTowel framework and Learning-Path- Manager-Code-Sample from Andrew Connell.
– Uses ShareCoffee Javascript library to make REST calls to SharePoint
– Available as a nuget package for easy install
2. ExpensesAngularApp test:
– This Project runs on NodeJS and executes End to End testing on Expenses Angular App
– Utilizes Protractor framework to do E2E testing
– Jasmine is used to write test specs
Source code:

Powershell to change UPN/Sign-in names for Office 365 users


In many cases after running the DirSync, Office 365 users are created with as Primary UPN.



Internally MS maintains two domains for federated users. One is “” which is the replica of on premise AD and other with “” on Azure AD.

It seems if the Dirsync is ran without “E-Mail” attribute on AD, Azure assigns “” as the default domain and primary UPN. Once the initial DirSync is complete, adding “Email” value to AD user object wont help.



As usual PowerShell comes to rescue. Idea is to use Windows Azure AD Module for Powershell and change the UPN of all the objects with .onmicrosoft UPN.


1) Download and Install Azure AD modules from

2) Connect to WAAD  service using Office 365 admin credentials

3) Filter all the users ending with  as their UPN

4) Change the UPN using Set-MsolUserPrincipalName

5) Generate reports before and after updates

Download the scripts here: Update-msolUpn.ps1 


#.SYNOPSIS ./Update-msolUpn.ps1
#PowerShell script to automate this task to change the all Office 365 user accounts with to
#Install Azure AD modules from before running this.

#Get Modules
$env:PSModulePath=$env:PSModulePath+";"+"C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell"
Import-Module Azure
Import-Module MSOnline

Get-Credential "" | Export-Clixml C:\GSI\scripts\GSIcred.xml #Store Credentials

#$count = 1 #For Testing the first result

$cred = Import-Clixml C:\GSI\scripts\GSIcred.xml

Connect-MsolService -Credential $cred

Get-MsolUser -All | Select-Object UserPrincipalName, Title, DisplayName, IsLicensed | export-csv –path C:\GSI\scripts\GSI_MSOL_Users_BeforeUpdate.csv

Get-MsolUser -All |
 Where { $_.UserPrincipalName.ToLower().EndsWith("") } |
 ForEach {
 #if($count -eq 1) #For Testing the first result
 # {
 $upnVal = $_.UserPrincipalName.Split("@")[0] + ""
 Write-Host "Changing UPN value from: "$_.UserPrincipalName" to: " $upnVal -ForegroundColor Magenta
 Set-MsolUserPrincipalName -ObjectId $_.ObjectId -NewUserPrincipalName ($upnVal)
 # }

Get-MsolUser -All | Select-Object UserPrincipalName, Title, DisplayName, IsLicensed | export-csv –path C:\GSI\scripts\GSI_MSOL_Users_AfterUpdate.csv


Azure hosted SharePoint apps using AngularJS and WebAPI – Part 3

This is final post of a three part series on exploring Azure hosted SharePoint apps using AngularJS and WebAPI.

Part 1: Why Cloud and AppModel?

Part 2: SQLAzure data via WebAPI:

Part 3: Azure hosted apps using AngularJS and WebAPI

Why AngularJS:

 Traditionally managed server-side programming used to develop enterprise apps. But now this pattern is changing in the enterprise application development industry.  It’s a change away from logic on the server side, and towards logic on the client side. To address these complex business logic Javascript should evolve from just a language to make DOM manipulations to powerful client side MVC/MVVM framework. AngularJS framework makes this shift at ease.





There are also few other frameworks on the same course but AngularJS is a clear leader owing to these facts:

1)       Dependency injection:

This is huge and my personal favorite. Using this, custom modules can be injected just like adding assemblies on the server side code. This makes life little easier design MVC/MVVM based projects with separation of concern, modularity etc. An Analogy to server side code is represented below




2)      HTML templating:

Over the past few years, Single Page App’s (SPA’s) are gaining of a lot of traction from front end developers and end users. HTML templating feature in Angular makes it possible to easily switch the HTML in SPA’s.

 3)      Two way binding:

Fellow Silverlight developers can understand the complexity of two-way binding using propertychange events back in the old days. But AngularJS databinding makes this right OOB

 4)      Community support:

Google continues to develop and maintain the library. Large community of developers has embraced the framework so ample support is available on Stackoverflow and AngularJS official site.

5)      Advance error handling and logging features

Why AngularJS on Provider hosted App:

 Instead of using server side code on Provider hosted app, client side code is used for a sole reason to utilize AngularJS framework. Some of the advantages include

  •  Single Page App (SPA)
  • Clean URL for easy navigation
  • Responsive design
  • No server side code
  • Scalable for further enhancements

Future enhancements may include:

1)       Adding Chrome controls to give SharePoint look and feel

2)      Authentication for WebAPI

3)      Functions to delete/update O365 and WebApi Data. etc


Design of this app is based on Hot Towel app from John Papa and the pluralsight course from Andrew Connell.

It requires a bit of learning to understand the AngularJS. Go through these resources for deep understanding

SPAngular APP:

1)       Create a new provider host app project in VS2013

2)      New Project -> App for SharePoint -> Provider Hosted App -> ASP.NET Web Forms Application -> Use Windows Azure Access Control Service ->finish


3)      Now click the web project -> Manage NuGet Packages


4)      Search “hot towel” and install HotTowel.Angular.



5)      Main benefit of using this project template is all the heavy lifting of implementing MVC project structure, logging, exception handling, angularJS, configuration comes OOB. This makes this bootstrap project easily extensible for custom functionalities.


6)      By default App project creates Query String tokens to store URL’s of Appweb , hostweb etc for reference in the future.


7)      AngularJS navigation is based on the URL manipulations. Its little hard to implement the navigation with these long URL’s. So the idea is to use a applauncherpage to store the Querystring values to cookies for future use and redirect to the main page with clean URL.

8)      Create applauncher.html and applauncher.js. Create an empty controller and all the JS references from index.html.

<!DOCTYPEhtml><!--// ** Step 1: Add AppLauncher:  **//-->



<title>App Launcher</title>


<bodydata-ng-controller="applauncher as vm">


<!--// ** Step 2: Add Angular libs:  **//-->

<!-- Vendor Scripts -->















<!-- Bootstrapping -->






<!-- common Modules -->





<!-- common.bootstrap Modules -->



<!-- app -->






<!--// ** Step 5: Create Add references **// -->

<!-- app Services -->








9)      In the applauncher.js call spappcontext angular service.

// ** Step 3: Add AppLauncher JS:  **//


'use strict';

var controllerId ='applauncher';

var app = angular.module('app');

app.controller(controllerId,['common','spappcontext', applauncher]);


function applauncher(common, spappcontext){

var getLogFn = common.logger.getLogFn;

var log = getLogFn(controllerId);


function activate(){

common.activateController([], controllerId)

.then(function(){ log('Activated App Launcher View');});





10)   Create SPappcontext.js and create createSPAppContext()and loadSPAppContext() functions to read the query string and store it to cookies. This also redirects to \index.html, a Single page app.


'use strict';

var serviceId ='spappcontext';

var app = angular.module('app');

app.service(serviceId,['common','$window','$location', spappcontext]);

function spappcontext(common, $window, $location){

var getLogFn = common.logger.getLogFn;

var log = getLogFn(serviceId);

var service =this;

var spweb ={





service.hostWeb = spweb;


function init(){

var test = jQuery.getQueryStringValue('SPHostUrl');










function loadSPAppContext(){

log('loading spcontext cookie');

service.hostWeb.providerUrl = $.cookie("ProviderUrl");

service.hostWeb.SPAppWebUrl = $.cookie("SPAppWebUrl");

service.hostWeb.SPHostUrl = $.cookie("SPHostUrl");


function createSPAppContext(){

log('writing spcontext cookie');

var ProviderUrl = $window.location.protocol +"//"+ $;

$.cookie("ProviderUrl", ProviderUrl,{ path:'/'});

var appWebUrl = decodeURIComponent(jQuery.getQueryStringValue('SPAppWebUrl'));

$.cookie("SPAppWebUrl", appWebUrl,{ path:'/'});

var url = decodeURIComponent(jQuery.getQueryStringValue('SPHostUrl'));

$.cookie('SPHostUrl', url,{ path:'/'});

$window.location.href = ProviderUrl +"/index.html";




11)    Now add host web SP JS libraries to index.html to for make JSOM calls against host web.

<!--// ** Step 7: Add SharePoint libs for JSOM calls **// -->





Now add the following code to web.config remove the static file issue on described here

<!--// ** Step: 8: To Resolve IIS Static file issue**//-->




<addname="AspNetStaticFileHandler" path="*" verb="*" type="System.Web.StaticFileHandler" />

<addname="StaticHTML" path="*.html" verb="GET,HEAD,POST,DEBUG,TRACE" modules="StaticFileModule" resourceType="File" requireAccess="Read" />




12)   Now use JSOM to call host web and REST calls to WebAPI. $q.defer() objects are used to  pass promise to the calling function. This enables clients to complete the DOM structure without waiting for results.( Host web contains a demo contact list with title “DemoCustomer”

// ** Step 6: Create Datacontext Service **//


'use strict';


var serviceId ='datacontext';

angular.module('app').factory(serviceId,['$rootScope','$resource','spappcontext','common', datacontext]);


function datacontext($rootScope,$resource, spappcontext,common){

var $q = common.$q;



var service ={

getPeople: getPeople,

getMessageCount: getMessageCount,

getUserName: getUserName,

getCustomers: getCustomers,

getSPContacts: getSPContacts



return service;


function getCustomers(){


var dfd = $q.defer();

var webApi = $resource('',{ Id:"@Id"},{ update:{ method:'PUT'}});

//   var webApi = $resource('http://localhost/AppWeb/api/Customer/:Id', { Id: "@Id" }, { update: { method: 'PUT' } });


var customers = data;







return dfd.promise;



function getUserName(){


var dfd = $q.defer();


// Standard function to get hostweb

var ctx =new SP.ClientContext(spappcontext.hostWeb.SPAppWebUrl);

var factory =new SP.ProxyWebRequestExecutorFactory(spappcontext.hostWeb.SPAppWebUrl);


var hostWebctx =new SP.AppContextSite(ctx, spappcontext.hostWeb.SPHostUrl);


var appWeb = ctx.get_web();

var hostWeb = hostWebctx.get_web();

var currentAppWebUser = appWeb.get_currentUser();

var currentHostWebUser = hostWeb.get_currentUser();








var userName = currentAppWebUser.get_title();


},function(sender, args){

console.log(args.get_message()+" "+ args.get_stackTrace());




return dfd.promise;



function getSPContacts()


var dfd = $q.defer();

// Standard function to get hostweb

var ctx =new SP.ClientContext(spappcontext.hostWeb.SPAppWebUrl);

var factory =new SP.ProxyWebRequestExecutorFactory(spappcontext.hostWeb.SPAppWebUrl);


var hostWebctx =new SP.AppContextSite(ctx, spappcontext.hostWeb.SPHostUrl);


var appWeb = ctx.get_web();

var hostWeb = hostWebctx.get_web();


var ContactList = hostWeb.get_lists().getByTitle('DemoCustomer');

var contactListItems = ContactList.getItems(SP.CamlQuery.createAllItemsQuery());




var enumerator = contactListItems.getEnumerator();

var SPContacts =[];


var currentItem = enumerator.get_current();

SPContacts.push({"FirstName": currentItem.get_item('FirstName'),"LastName": currentItem.get_item('Title')});


var SPContactsObj = SPContacts;



},function(sender, args){

console.log(args.get_message()+" "+ args.get_stackTrace());



return dfd.promise;




13)   Now modify dashboard.js to call data service functions defined above and add spinner while waiting for results.


'use strict';

var controllerId ='dashboard';

angular.module('app').controller(controllerId,['common','datacontext', dashboard]);


function dashboard(common, datacontext){

var getLogFn = common.logger.getLogFn;

var log = getLogFn(controllerId);


var vm =this; ={

title:'Hot Towel Angular',

description:'Hot Towel Angular is a SPA template for Angular developers.'


vm.messageCount =0;

vm.people =[];

vm.SPContacts =[];

vm.Customers =[];

vm.title ='Dashboard';

vm.busyMessage ='Please wait ...';

vm.isBusy =true;

vm.spinnerOptions ={













function activate(){

var promises =[getMessageCount(), getPeople(), getSPContacts(), getCustomers()];

common.activateController(promises, controllerId)

.then(function(){ log('Activated Dashboard View');});



function getCustomers(){


return datacontext.getCustomers().then(function(data){


return vm.Customers = data;




function getMessageCount(){

return datacontext.getMessageCount().then(function(data){

return vm.messageCount = data;




function getPeople(){

return datacontext.getPeople().then(function(data){

return vm.people = data;





function getSPContacts(){


return datacontext.getSPContacts().then(function(data){

return vm.SPContacts = data;





function toggleSpinner(on){ vm.isBusy = on;}



14)   Now add remote endpoint to the appmanifest.xml


15)   Now navigate to /_layouts/15/appregnew.aspx to generate client Id and client secret. Note down these values.


16)   Now right click the web project and select publish to select a new publishing profile


17)   Seed the values of the ClientID and Client Secret noted earlier.


18)   Now select the created profile and deploy to Azure Website.


19)   Add a site name and click create


20)   Keep the default settings and click publish.


21)    Now package the app and upload the app to the Office 365 site.


22)   Now clicking the app will navigate to the provider hosted app with displays data from both Office 365 and WebAPI.


This project is hosted in codeplex for download: 

Azure hosted SharePoint apps using AngularJS and WebAPI – Part 2

This is second post of a three part series on exploring Azure hosted SharePoint apps using AngularJS and WebAPI.

Part 1: Why Cloud and AppModel?

Part 2: SQLAzure data via WebAPI:

Part 3: Azure hosted apps using AngularJS and WebAPI

SQLAzure data via WebAPI:

This is the continuation of this post on creating Azure hosted enterprise apps using AngularJS and WebAPI.

WebAPI is a framework for building RESTful applications which enables client browsers to tap in to database using HTTP  GET, POST, DELETE requests.  This involves following steps:

Note: Following steps require valid Azure subscription. Microsoft offers free credits for MSDN subscribers.

1)       Create a SQL server instance in Azure management portal -> SQL Databases -> New



2)      Create SQL Database. I am using AdventureWorksLT2012 database for this demoapp. This is downloaded from . After restoring this app on local instance, create a database in SQLAzure with the same name.


3)      Once the database is created, the properties can be accessed by clicking through it.


4)      Now migrate the SQL DB from local instance to SQL azure using SQLAzure Migration Wizard.


5)      SQLAzure supports only a subset of SQL features. Some of the limitations are listed here . XML Schema collections are not supported so uncheck it.


6)      Now click next to generate SQL script to create database. Script displays non supported items in RED.

Fix these items and re-generate the script until all these errors are cleared. Follow this article to resolve some of the most common errors


7)      Now run this script on SQLAzure instance by keying the connection details of Azure DB created earlier


8)      Now connect to SQLAzure using SSMS


9)      Now to expose the database via WebAPI.

To do this install Azure SDK by following this link

Install Entity Framework Powertools to convert SQL objects to .net entities

10)   Create new “Windows Azure Cloud Service” project. This creates a project with web role. Refer “Cloud Services” section in the article to understand more on this. Basically this project creates a VM and IIS in Azure to host WebAPI web services on deployment.



11)    Now Right Click WebRole project -> Entity framework -> Reverse Engineer Code First and connect to SQLAzure DB created earlier. This will generate all the required entities.


12)   This generates table, table mapping and database context classes.


13)   Now create a controller of customer class using Scaffolding. Scaffold templates are used to generate code for basic CRUD operations for WebApi project against database using DB entity objects generated earlier.







14)   Add  navigate to App Start -> WebAPIConfig.cs and add the following code highlighted under step 2 to enable JSON

public static void Register(HttpConfiguration config)


// ** Step: 2: Enable JSON **//

// Web API configuration and services

var json = config.Formatters.JsonFormatter;

json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;


// Web API routes




name: "DefaultApi",

routeTemplate: "api/{controller}/{id}",

defaults: new { id =RouteParameter.Optional }


// ** Step: 3: Enable CORS **//


var cors =newEnableCorsAttribute("*", "*", "GET, POST, OPTIONS");




15)   Now Right Click WebRole Project -> Manage Nuget Packages ->Type Cors and install the WebAPI 2.1 cross origin support. This API is used to enable cross origin services for the WebAPI.



16)   Now add the code to highlighted under “step 3” enable CORS

17)   This will generate required WebApi controller to service Read, Delete and update operations. Right click WebApi project and publish.


18)   This will take few minutes to spin up a VM and publish these resources in Azure. Once the deployment is complete, data can be accessed from WebApi service.


19)   Now click the new cloud service created via Azure management portal


20)   Navigate to “Instances” tag and click “Connect” button to remote into VM


21)   Install “IP and Domain restrictions” role on the VM


22)   Now open IIS and Navigate to WebAPI service web and click “IP Address and Domain restrictions” and add all the client IP’s which requires access to WebAPI.



This project is hosted in codeplex for download: