Using Azure’s AI for Search with AngularJS and ASP.Net MVC

Azure’s AI tools are easy to use and can extend the functionality of your app or web site with a few steps. I’m going to show you how to set up Azure Search in this tutorial.

In Part one we will add the accounts and tools needed to search

In Part two we will build the web site to leverage Azure’s Search AI

First, login to Azure at and add a new Storage Account:

2019-03-11 12_38_24-Home - Microsoft Azure.png

Once you’ve filled in the simple form, click Blobs to add a new Blob which will store your documents:

2019-03-11 12_39_50-bahaisearchstorage - Microsoft Azure.png

Now that you’ve got a blob you can add documents and folders via the SDK in your app, or with Microsoft Azure Storage Explorer. We’ll use the latter:

When you open Storage Explorer  up, navigate to your account and open your Storage Account and Blob and drag in some files. Word, PDF, Excel, Text etc:

2019-03-11 12_43_26-Microsoft Azure Storage Explorer.png

Now we’ll add some Search tools to our Azure account, click the Search Services and add a new service. Make sure the data center you choose here matches your data center used for the Blob storage.

2019-03-11 12_44_45-bahaisearch - Microsoft Azure.png

Once you’ve added an Index to your Search, you are ready to try out the search. Tap the Search Explorer button in your Search Service:

2019-03-11 12_46_11-bahaisearch - Microsoft Azure.png

A simple Azure UI will appear letting you search your documents in Test.

2019-03-11 12_48_07-Search explorer - Microsoft Azure.png

In the next article I’ll show you how to search using the SDK in your own apps.

Use that I created an AngularJS based search tool in a few hours. You can try it here:


2019-03-11 12_49_46-Baha'i Search.png








VSTS Unit Testing for ASP.NET Core

download.pngUp until recently setting up VSTS for .Net Core unit testing was a bit tricky. In this simple post I’ll show you have you can enable it using the new .NET Core Task.

Step 1: Add .NET Core Task

2018-08-10 08_40_31-Gateway - Visual Studio Team Services.png

Step 2: Click the Task, then change Command to test

2018-08-10 08_41_13-Gateway - Visual Studio Team Services.png

Step 3: Add your projects to be tested

2018-08-10 08_41_42-Gateway - Visual Studio Team Services.png

Creating a Resiliant API call with Retry

Polly-Logo@2x.pngSometimes when we call an API over HTTP it fails and needs to be re-tried. Using Polly I’ll show you a simple way to implement a retry strategy.

Here’s a simple API call that will fail half the time.

public class Api
    Random rnd = new Random(DateTime.Now.Millisecond);
    public async Task<stringGetHtml(string url)
        if (rnd.Next(1,10)<5)
            url = "";
        return await new HttpClient().GetStringAsync(url);

Let’s add the Polly Nuget package and then change the API to this:

public class Api
    public async Task<stringGetHtml(string url)
        var policyResult = await Policy<string>
            .WaitAndRetryAsync(5, retryNumber => TimeSpan.FromSeconds(.5))
            .ExecuteAndCaptureAsync(async () => await DoTheActualWork(url));
        return policyResult.Result;
    Random rnd = new Random(DateTime.Now.Millisecond);
    public async Task<stringDoTheActualWork(string url)
        if (rnd.Next(1,10)<5)
            url = "";
        return await new HttpClient().GetStringAsync(url);

We added a wrapper around GetHtml() It will retry the call 5 times if it gets a HttpRequestException.

In actual implementation you’ll want to check for Status codes or other failure conditions.

There’s a lot more you can add with Polly like checking for values in the result:

var policyResult = await Policy<string>
    .OrResult(s=>s.Contains("We are sorry, the page you requested cannot be found."))
    .WaitAndRetryAsync(16, retryNumber => TimeSpan.FromSeconds(.5))
    .ExecuteAndCaptureAsync(async () => await DoTheActualWork(url));


Kendo Controls in an AngularJS ng-repeat

Mark_verticalKendo has long been an awesome JavaScript framework for UI controls. I had to build a user management system and needed to dynamically show a number of Kendo controls, all created via an AngularJS ng-repeat.

Kendo is smart enough to know that the item in the repeat, a user in this case, is the bound object and will keep a reference to it.

<div  ng-repeat="user in model.users">
        <input kendo-numeric-text-box
               k-min="0" k-max="10000000"
               k-ng-model="user.wealth" />


AngularJS: ng-repeat with Groups

1_iOmwue1uxW2O6sbDUEItPw.jpgHere’s a quick tip on how to display grouped data in AngularJS on your ASP.Net Core page (or any other).

Let’s say your have a list of cities, with their associated country already sorted by country then by city:

Canada Toronto
Canada Ottawa
Canada Vancouver

USA Boston
USA New York

To display the Country once, then all the cities, you can use this:

<div ng-repeat="(key, value) in data.cities| groupBy: 'country'">
    <div ng-repeat="row in value">


ASP.Net Core 2: Quick and Dirty Windows Authentication

410329-636167162756711825-16x9.jpgHere’s the bare minimum you need to add to your ASP.Net Core 2 application to restrict it to certain Windows Active Directory groups.




Step 1: Enable Windows Authentication in the Project Properties:


Step 2: add this to your Web.Config <aspNetCore> node:

 <aspNetCore forwardWindowsAuthToken="true"

Step 3: Enable Windows Authentication in IIS


Step 4: Add Authentication to the ConfigureServices call in your Startup.cs

        public void ConfigureServices(IServiceCollection services)
            // IISDefaults requires the following import:
            // using Microsoft.AspNetCore.Server.IISIntegration;
            services.Configure<IISOptions>(options => {
                options.AutomaticAuthentication = true;
                options.ForwardClientCertificate = true;

Step 5: Add this to your Configuration call in Startup.cs


Step 6: Add [AllowAnonymous] to Controllers which need anonymous access

Step 7: Add [Authorize(Roles…)] to controllers that need to be restricted

namespace App.Web.Areas.Kxg.Controllers
    [Authorize(Roles = "MyAD\\Developer,MyAD\\IT_Support_Desk_Staff ")]
    public class CustomerSearch : Controller


To get a list of the Groups used in [Authorize], in PowerShell type:

whoami /groups