# Wednesday, 25 May 2016

Here is an interview I conducted recently with Victor Cintron of DimDrop – a startup that uses location-based services to improve communication. They are deploying a number of open source technologies to Microsoft Azure.

Startup Stories: An Interview with Victor Cintron, CEO of DimDrop

Azure | DevRadio | Interviews | OSS | Startups | Video
Wednesday, 25 May 2016 06:47:04 (GMT Daylight Time, UTC+01:00)
# Monday, 23 May 2016
Monday, 23 May 2016 10:09:00 (GMT Daylight Time, UTC+01:00)
# Saturday, 21 May 2016

Last month, I had the privilege of attending the AWS Summit in Chicago. It was a great experience for me because, although I do a lot of work with cloud computing, I have very little experience with the Amazon Web Services (AWS) platform.

The most interesting session I attended was about a service called "Aurora" (Amazon tends to give all their services catchy names). This is a relational database that looks and acts almost exactly like MySQL but runs much faster. The official product page brags that Aurora is a "MySQL-compatible relational database with 5X performance", however the session I attended claimed that they found cases in which Aurora was 63 times faster than MySQL. The presenters didn't share details of those cases, but even if results are only a fraction of that speed, it's still an impressive performance improvement.

Because Aurora is MySQL-compliant, you should be able to plug it into any application and use it just like MySQL. The SQL syntax is identical and the management tools will be familiar to anyone used to managing MySQL.

Of course, the fact that Aurora is hosted on a cloud platform like AWS gives it the advantage of high availability and flexible scaling that cloud computing offers.

Since most of my cloud computing experience is with Microsoft Azure, I tend to use Azure as a reference point for the services I saw at this summit. I was drawn to Aurora in part because I'm not aware of the same offering in Microsoft Azure.

MySQL as a service is available on Azure, but it's offered and supported by ClearDb - a third party.  If you want better performance or scalability on Azure than that offered by ClearDb, you will need to either switch to a different database or create a Virtual Machine and install MySQL on that, in which case you would be using Infrastructure as a Service, instead of Software as a Service.

In many cases, this is a non-issue. If you are building a new application, you have the flexibility to choose your preferred database technology. MySQL and SQL server have very similar languages; and, although I won't get into a debate here as to which is "better", it would be difficult to argue that SQL server is significantly less reliable or enterprise-ready than MySQL.

But there are times when you don't have a choice of database technologies. For example, if you have a large legacy application that you want to migrate to Azure, it may be a daunting task to migrate every stored procedure and SQL statement to use T-SQL.  Or if you are using a framework that is specifically built on top of MySQL, it makes sense to use that database, rather than re-writing the entire data access layer. Luckily, some frameworks have alternative data access layers. For example, Project Nami is a data access layer for WordPress that uses SQL Server as a data store, rather than MySQL.

Although the various cloud computing companies follow one another and are likely to build a service when they see traction on their competitor's platform, I find it interesting to see these gaps in offerings.

Saturday, 21 May 2016 11:28:00 (GMT Daylight Time, UTC+01:00)
# Friday, 20 May 2016

Here is a recent conversation I had with Sean Goltz and Addison Cameron-Huff of Global-Regulation, a company that assists researchers who are searching for international law documents. They are deploying a variety of open source technologies on Microsoft Azure.

Watch this interview below or follow this link to the interview.

Friday, 20 May 2016 14:39:33 (GMT Daylight Time, UTC+01:00)
# Wednesday, 18 May 2016

The Newtonsoft.Json library contains a number of tools for working with JSON from within your .NET application.

New ASP.NET applications created in Visual Studio already contain a reference to the Newtonsoft.Json library. But if you want to add the library to a different project type or if you want to update the version installed by default with an ASP.NET application, you can right-click your project in the Visual Studio Solution Explorer and select "Manage NuGet Package..." and search for Newtonsoft.Json. Select the "Newtonsoft.Json" package (Fig 1) and click either "Install" or "Update".

Newtonsoft is very good at serializing .NET objects into JSON objects.

One feature that I find useful is its ability to rename attributes in my classes. For example, if I have a class named "SocialSecurityNumber" in my C# class and the client consuming my JSON object expects that same property to be named "ssn", I can make this transformation declaratively by adding the JsonProperty attribute to the class property, as shown in Listing 1.

public string SocialSecurityNumber { get; set; } 

By convention, C# developers tend to name public properties with mixed case (capitalize the first letter of each word); while JavaScript and JSON developers tend to name properties using Camel casing (capitalize the first letter of each word, except the first word). In the past, I used the JsonProperty attribute to accomplish this, renaming every variable that would be serialized to JSON, as in the following example:

public string FirstName { get; set; }
public string LastName { get; set; }

For projects with many objects and many properties, this can be a tedious task. Fortunately, I recently learned a shortcut.

ASP.NET contains a Formatters class that controls how items are formatted and Newtonsoft.Json can tap into this. The following code, when run at the start of your application, converts all properties to Camel-Case as you transform them to JSON.

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

I added this code to the Register method of the WebApiConfig class in my ASP.NET MVC project, so that it is run when the application starts up, before any serialization is done.

Another useful setting is to add carriage returns and line feeds to the JSON that is created. This has the disadvantage of making your JSON slightly larger; but it makes it much easier for human beings to read, which can be very useful during debugging. This is accomplished with the following line:

settings.Formatting = Formatting.Indented; 

The full listing in the Register() method is shown below:

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

Using the tools in the Newtonsoft.Json library, we can easily adhere to the conventional naming conventions of whatever platform in which our data is used.

C# | JavaScript | Web
Wednesday, 18 May 2016 20:18:48 (GMT Daylight Time, UTC+01:00)
# Tuesday, 17 May 2016

Gary Numan was everything I did not expect.

GaryNuman (5) He came to Chicago for 3 nights  at Metro night club in Wrigleyville. Each night he promised to perform a different album from early in his career -  "Replicas" on Sunday; "The Pleasure Principle" Monday and "Telekon" on Tuesday. I chose to attend Sunday because his 1979 album "Replicas" has always been my favourite of his. This was an album I embraced in high school a year before the rest of America learned of Gary Numan with the release of "The Pleasure Principle" and its wildly popular "Cars".

For me, Replicas was always the definitive Gary Numan album. Its layers of electronic melodies and its lyrics about a dystopian future spoke to the adolescent me and the album still holds up decades later.

GaryNuman (2) Numan performed every song from the "Replicas" album and I was impressed by his enthusiasm for songs that he released 3 decades ago.

I don't recall ever attending a concert in which I knew in advance the songs the artist would play. But he surprised us - first by mixing the order of the original album and (more significantly) updating the arrangements.

The electronic music that made him famous is still impressive. "Down in the Park" and "I Nearly Married a Human" featured impressive keyboards and unusual sounds. But, he transformed "Me! I Disconnect From You" from a hypnotic synth-pop tune into a rock song that any post-punk garage band would be proud of. The guitar bass drums came to the fore on a number of his songs, making them more rocking and less ethereal.

Replicas I expected a stiff, robotic, stoic Gary Numan - similar to the mannequin pose on the Replicas album cover. Instead, the audience was treated to an energetic performer dancing to his songs and bringing a renewed passion to his old music.

The only downside was the venue. The fact that Metro only accepts cash was a disappointing surprise, but its General Admission format made it difficult for most attendees to see the stage. There are a limited number of tables one can reserve at more than double the GA price and I'm debating doing this when Echo & the Bunnymen play there in the Fall.

GaryNuman (3) But I found a bit of floor space to enjoy the show and enjoy it I did - from the music to the strobe lights. Thanks to Numan's energy this concert exceeded my expectations.

Tuesday, 17 May 2016 15:56:18 (GMT Daylight Time, UTC+01:00)
# Monday, 16 May 2016
Monday, 16 May 2016 13:20:43 (GMT Daylight Time, UTC+01:00)
# Sunday, 15 May 2016

In an earlier article, I described how to call the Cognitive Services API from JavaScript. The key parts of the code (using the jQuery library) is shown below:

var subscriptionKey = "cd529ca0a97f48b8a1f3bc36ecd73600";
var imageUrl = $("#imageUrlTextbox").val();
var webSvcUrl = "https://api.projectoxford.ai/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=true&returnFaceAttributes=age,gender,smile,facialHair,headPose,glasses";
    type: "POST",
    url: webSvcUrl,
    headers: { "Ocp-Apim-Subscription-Key": subscriptionKey },
    contentType: "application/json",
    data: '{ "Url": "' + imageUrl + '" }'
}).done(function (data) {
        // ... 
        // Code to run when web service returns data...
        // ...

Do you spot the problem with this code?

Although it works very well from a functional point of view, it has a security flaw” As with all Cognitive Services APIs, the Face API requires you to pass a key in the header of your HTTP request. Because there is no easy way to hide this key, it is easy for a hacker to steal your key. Using your key, they can make calls and charge them to your account - either using up your quota of free calls or (worse) charging your credit card for their calls.

One way to hide the key is to make the call to Cognitive Services from a custom web service. This web service can be a simple pass-through, but it allows you to hide the key on the server, where it is much more difficult for a hacker to find it.

We can use Web API to create this custom web service. With Web API, is a simple matter to store the Subscription Key in a secure configuration file and retrieve it at run time. The relevant code goes in an ApiController class as shown below.

// POST: api/Face
public IEnumerable<Face> Post([FromBody]string imageUrl)
    return GetFaceData(imageUrl);
public static IEnumerable<Face> GetFaceData(string imageUrl)
    var webSvcUrl = "https://api.projectoxford.ai/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=true&returnFaceAttributes=age,gender,smile,facialHair,headPose,glasses";
    string subscriptionKey = ConfigurationManager.AppSettings["SubscriptionKey"];
    if (subscriptionKey == null)
        throw new ConfigurationErrorsException("Web Service is missing Subscription Key");
    WebRequest Request = WebRequest.Create(webSvcUrl);
    Request.Method = "POST";
    Request.ContentType = "application / json";
    Request.Headers.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
    using (var streamWriter = new StreamWriter(Request.GetRequestStream()))
        string json = "{"
        + "\"url\": \"" + imageUrl + "\""
        + "}"; 
        var httpResponse = (HttpWebResponse)Request.GetResponse(); 
        string result = "";
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            result = streamReader.ReadToEnd();
        List<Face> faces = JsonConvert.DeserializeObject<List<Face>>(result);
        return faces;

Of course, we could also use the .NET library to abstract the call to the Face API, but I wanted to keep this code as close to the original JavaScript code as possible.  This method returns a List of Face objects. The Face object maps to the JSON data returned by the Face API. You can see this class below.

public class Face
    public string FaceId { get; set; }
    public FaceRectangle FaceRectangle { get; set; }
    public FaceLandmarks FaceLandmarks { get; set; }
    public FaceAttributes FaceAttributes { get; set; }

Now, we can modify our JavaScript code to call our custom API, instead of calling Face API directly, and we can eliminate the need to pass the key from the client-side JavaScript, as shown below:

var imageUrl = $("#imageUrlTextbox").val();
webSvcUrl = "api/face";
    type: "POST",
    url: webSvcUrl,
    data: JSON.stringify(imageUrl),
    contentType: "application/json;charset=utf-8"
}).done(function (data) { 
// ... 
// Code to run when web service returns data...
// ...

In this listing, we have removed the Subscription-Key from the Header and we have changed the Web Service URL. This is JavaScript is calling a web service in its own domain, so it is trusted. The default Cross-Site scripting settings of most web servers will keep JavaScript outside this domain from accessing our custom web service.

This pattern works with any of the Cognitive Services APIs. In fact, it works with any API that requires the client to pass a secure key. We can abstract away the direct call to that API and hide the key on the server, making our code more secure.


  • You can find the full code of the sample described above here.
  • You can find the code for the “unprotected” sample here.
Sunday, 15 May 2016 00:50:49 (GMT Daylight Time, UTC+01:00)
# Friday, 13 May 2016

Microsoft Cognitive Services (MCS) allows you to tap into the power of Machine Learning and perform sophisticated analysis of photographs, simply by calling a web service.

The Face API in MCS returns an array of all the faces found in a photo, along with information about each face, such as the location of the eyes, nose, and mouth; the age and gender of the person, and information about eyeglasses and facial hair.

You can sign up to use MCS for free at https://www.microsoft.com/cognitive-services/. Information specific to the Face API can be found at https://www.microsoft.com/cognitive-services/en-us/face-api. (fig 1)

Fig. 1

To use the Face API, click the [Get Started for Free] button. You will see a list of subscription keys. Scroll down to "Face" section and click "Copy" next to one of the Face Subscription keys to save it to your clipboard or click "Show" to reveal the key.

Fig. 2

To call the Face API, send an HTTP POST request to https://api.projectoxford.ai/face/v1.0/detect

You may add optional querystring parameters to the above URL:

returnFaceID: If set to "true", the web service will return a GUID representing the face, so that you can make repeated inquiries about this face.

returnFaceLandmarks: If set to "true", the web service will return a "faceLandmarks" object containing a list of points identifying where location of the edges of the eyes, eyebrows, nose, and mouth.

returnFaceAttributes: A comma-delimited list of face attributes the web service should return. Allowable attributes are
age: an age number in years.
gender, smile, facialHair, headPose, and glasses.

The service will always return a rectangle identifying the outline of the face. Adding more properties to return will, of course, slow down both the computation and the download of the data.

You must pass the subscription key (described above) in the header of your HTTP request as in the following example:


The photo itself will be in the body of the POST request. In the content-type header parameter, you can specify how you plan to send the photo to the server. If you plan to send a link to the URL of a photo, set the content-type to "application/json"; if you plan to send the photo as binary data, set the content-type to "application/octet-stream".

The body of the request contains the image. If you selected "application/json" as the content type, send the URL in the following JSON format:

{ "Url": "http://davidgiard.com/themes/Giard/images/logo.png"}

If successful, the web service will return (formatted as JSON) an array of "face" objects - one for each face detected in the photo. Each object will contain the top, left, height, and width values to define a rectangle outlining that face. If you declared that you want more data (e.g., FaceID, Face Landmanrks, and Face Attributes), that data will also be returned in each face object.

Below is an example of JavaScript / jQuery code to call this API.

var subscriptionKey = "Copy your Subscription key here"; 
var imageUrl = "http://davidgiard.com/themes/Giard/images/logo.png";
var webSvcUrl = "https://api.projectoxford.ai/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=true&returnFaceAttributes=age,gender,smile,facialHair,headPose,glasses";
var outputDiv = $("#OutputDiv");
    type: "POST",
    url: webSvcUrl,
    headers: { "Ocp-Apim-Subscription-Key": subscriptionKey },
    contentType: "application/json",
    data: '{ "Url": "' + imageUrl + '" }'
}).done(function (data) { 
    if (data.length > 0) {
        var firstFace = data[0];
        var faceId = firstFace.faceId;
        var faceRectange = firstFace.faceRectangle;
        var faceWidth = faceRectange.width;
        var faceHeight = faceRectange.height;
        var faceLeft = faceRectange.left;
        var faceTop = faceRectange.top; 
        var faceLandmarks = firstFace.faceLandmarks;
        var faceAttributes = firstFace.faceAttributes; 
        var leftPupil = faceLandmarks.pupilLeft;
        var rightPupil = faceLandmarks.pupilRight;
        var mouth = faceLandmarks.mouthLeft;
        var nose = faceLandmarks.noseLeftAlarOutTip;
        var mouthTop = faceLandmarks.upperLipTop;
        var mouthBottom = faceLandmarks.underLipBottom;
        leftEyeWidth = faceLandmarks.eyebrowLeftInner.x - faceLandmarks.eyebrowLeftOuter.x;
        rightEyeWidth = faceLandmarks.eyebrowRightOuter.x - faceLandmarks.eyebrowRightInner.x;
        mouthWidth = faceLandmarks.mouthRight.x - faceLandmarks.mouthLeft.x; 
        var mouthLeft = faceLandmarks.mouthLeft;
        var mouthRight = faceLandmarks.mouthRight;
        var mouthTop = faceLandmarks.upperLipTop;
        var mouthBottom = faceLandmarks.underLipBottom; 
        var outputText = "";
        outputText += "Face ID: " + faceId + "<br>";
        outputText += "Top: " + faceTop + "<br>";
        outputText += "Left: " + faceLeft + "<br>";
        outputText += "Width: " + faceWidth + "<br>";
        outputText += "Height: " + faceHeight + "<br>";
        outputText += "Right Pupil: " + rightPupil.x + ", " + rightPupil.y + "<br>";
        outputText += "Left Pupil: " + leftPupil.x + ", " + leftPupil.y + "<br>";
        outputText += "Mouth: <br>";
        outputText += " -Left: " + mouthLeft.x + ", " + mouthLeft.y + "<br>";
        outputText += " -Right: " + mouthRight.x + ", " + mouthRight.y + "<br>";
        outputText += " -Top: " + mouthTop.x + ", " + mouthTop.y + "<br>";
        outputText += " -Bottom: " + mouthBottom.x + ", " + mouthBottom.y + "<br>";
        outputText += "Attributes:" + "<br>";
        outputText += "age: " + faceAttributes.age + "<br>";
        outputText += "gender: " + faceAttributes.gender + "<br>";
        outputText += "smile: " + (faceAttributes.smile || "n/a") + "<br>";
        outputText += "glasses: " + faceAttributes.glasses + "<br>";
    else {
        outputDiv.text("No faces detected."); 
}).fail(function (err) {
    $("#OutputDiv").text("ERROR!" + err.responseText);
service call is performed by the following line: 
    type: "POST",
    url: webSvcUrl,
    headers: { "Ocp-Apim-Subscription-Key": subscriptionKey },
    contentType: "application/json",
    data: '{ "Url": "' + imageUrl + '" }' 

This request is Asynchronous, so the "done" function is called when it returns successfully.

}).done(function (data) { 

The function tied to the "done" event parses through the returned JSON and displays it on the screen.

If an error occurs, we output a simple error message to the user in the "fail" function.

}).fail(function (err) {
          $("#OutputDiv").text("ERROR!" + err.responseText);

The rest of the code above simply grabs the first face in the JSON array and drills down into properties of that face, displaying those properties in a DIV on the page.

For example, in the attached site.css stylesheet, I’ve defined 2 classes - .Rectangle and .FaceLabel - that initially hide objects on the page via the display: none style. These classes also set the position to “absolute” allowing us to position them exactly where we want within a container. The z-order is incresed, so that these items will appear on top of the face in the picture.  The relevant CSS is shown below:

    opacity: 0.3;
    z-index: 10;
    position: absolute;
    display: none;
    position: absolute;
    z-index: 20;
    display: none;
    font-size: 8px;
    padding: 0px;
    margin: 0px;
    background-color: white;
    color: black;
    padding: 1px;

Our page contains object with these classes to identify parts of the face identified. Initially, they will be invisible until we determine where to place them via the information returned by the Face API.

<div id="PhotoDiv">
    <img id="ImageToAnalyze" src="images/CartoonFace.png">
    <div class="FaceLabel" id="LeftEyeDiv">LEFT</div>
    <div class="FaceLabel" id="RightEyeDiv">RIGHT</div>
    <div class="FaceLabel" id="NoseDiv">NOSE</div>
    <div class="FaceLabel" id="MouthDiv">MOUTH</div>
    <img src="images/Rectangle.png" id="Rectangle">

When the call to the Face API web service returns successfully, we drill down into the returned JSON to find out the outline of the face and the location of the eyes, nose, and mouth. Then, we make these objects visible (set the display style to “block”)  and place them above the corresponding facial feature (set the “top” and “left” styles). In the case of the Rectangle image, we also resize it to cover the face detected. The rectangle’s “opacity” style is 0.3, making it translucent enough to see the face behind it. Here is the JavaScript to accomplish this:

$("#Rectangle").css("top", faceTop);
$("#Rectangle").css("left", faceLeft);
$("#Rectangle").css("height", faceHeight);
$("#Rectangle").css("width", faceHeight);
$("#Rectangle").css("display", "block");
$("#LeftEyeDiv").css("top", leftPupil.y);
$("#LeftEyeDiv").css("left", leftPupil.x);
$("#LeftEyeDiv").css("display", "block");
$("#RightEyeDiv").css("top", rightPupil.y);
$("#RightEyeDiv").css("left", rightPupil.x);
$("#RightEyeDiv").css("display", "block");
$("#NoseDiv").css("top", nose.y);
$("#NoseDiv").css("left", noseHorizontalCenter);
$("#NoseDiv").css("display", "block");
$("#MouthDiv").css("top", mouthVerticalCenter);
$("#MouthDiv").css("left", mouthTop.x);
$("#MouthDiv").css("display", "block");

Below is the output of the web page analyzing a photo of my face:


As you can see, calling the Cognitive Services Face API, is a simple matter of making a call to a web service and reading the JSON data returned by that service.

You can find this code in my GitHub repository.

Friday, 13 May 2016 10:11:00 (GMT Daylight Time, UTC+01:00)
# Thursday, 12 May 2016

Microsoft Cognitive Services is a set of APIs built on Machine Learning and exposed as REST Web Services. The Speech API offers a way to listen to speech and convert it into text.

GCast 16: Cognitive Services - Speech to Text

Thursday, 12 May 2016 13:10:38 (GMT Daylight Time, UTC+01:00)