Learning Microsoft Azure Review

Introduction

I was recently asked by Packt Publishing to do a review of their title Learning Microsoft Azure, and so I did.

It wasn’t the first time I did a review on an Azure book, I also reviewed Microsoft Azure Development Cookbook, Second Edition, and you can see my review here.

This time, it is an introductory book, where the reader is introduced to Microsoft Azure, and guided as he/she develops a full solution for an imaginary industrial bakery, from end to end, including a mobile app. It covers technologies such as ASP.NET MVC 5, Windows Phone 8, Entity Framework Code First and Web API, always using C# and .NET as the backing framework. At the end of each chapter, there’s a questions and answers page where we can assess our level of understanding of the topics that were discussed in it.

The author is Geoff Webber-Cross (@webbercross), which also authored another book on Azure and Windows Phone.

Chapter 1: Getting Started with Microsoft Azure

The first chapter, as we might expect, does an introduction to cloud computing and the Microsoft Azure service, presents a decision framework for aiding in selecting a cloud service as opposed to on-premises, guides the reader in creating an Azure account including it’s many services and costs, and lists the most relevant terms that we will be encountering throughout the book.

Chapter 2: Designing a System for Microsoft Azure

Here we are presented with the sample scenario, its objectives and requirements and the architectural vision of it. Different views on the system and its subsystems are presented and for each the technical decisions are explained.

Chapter 3: Starting to Develop with Microsoft Azure

Next we setup the development environment, choose a Visual Studio edition, download the required SDK and create a project to be published in our Azure account. Visual Studio Online is also presented and it’s integration with Azure, namely, in order to ensure continuous integration and delivery.

Chapter 4: Creating and Managing a Windows Azure SQL Server Database

Here we get an overview of the SQL functionality of Azure, how to create and manage databases using the portal, Visual Studio and the SQL Server Management Studio, then we learn how to use Entity Framework Code First to access and manipulate its data, and to migrate to and from different versions using the Migrations API.

Chapter 5: Building Azure MVC Websites

This chapter explains how we can build an MVC application using OAuth authentication (social accounts such as Twitter, Facebook, Google and Microsoft Live). It goes on explaining how we can set up custom domains and SSL certificates for HTTPS and how to integrate the Azure Active Directory for single sign-on and custom permissions.

Chapter 6: Azure Website Diagnostics and Debugging

This one is about diagnosing problems and debugging our applications. It presents the basic built-in tracing and logging features of Azure and how we can obtain this information and goes on to show how we can use table storage and blobs for custom storing of structured logs and its querying. Kudu is briefly introduced and at the end we learn how to do remote debugging.

Chapter 7: Azure Service Bus Topic Integration

Next up is Service Bus, Azure’s enterprise service bus service. We learn how to configure it, create and manage topics using the portal and how to use the service from our MVC application and expose it as a service.

Chapter 8: Building Worker Roles

The next chapter is about Worker Roles, a feature of Azure Websites that performs disconnected (non web-related) tasks. The reader is guided in creating a Worker Role with Visual Studio, executing it in the Emulator and publishing it to Azure. The example presented builds on the Service Bus topics discussed in the previous chapter. We also learn about other scheduling mechanism of Azure, Scheduler jobs, and implement an example using Queues.

Chapter 9: Cloud Service Diagnostics, Debugging, and Configuration

Here we learn about configuring and using the diagnostics features of Cloud Services, again expanding the concepts introduced in chapter 6. We talk about IntelliTrace and Remote Debugging and on how to connect to our virtual machines with Remote Desktop. Finally we are given an example on how to use script tasks to automate common needs.

Chapter 10: Web API and Client Integration

This chapter introduces ASP.NET Web API, Microsoft’s latest technology for building REST web services and SignalR, for asynchronous, duplex, real-time communication between web clients and the server. The provided example shows how to integrate these two technologies to broadcast messages to connected clients, including a desktop Windows Presentation Framework (WPF) application. In the end we learn how to use the Active Directory to authorize accesses to our services.

Chapter 11: Integrating a Mobile Application Using Mobile Services

Coming closer to the end, this chapter walks the reader on the various aspects of building a mobile client that connects to the cloud using Azure Mobile Services. We see how to implement a mobile-enabled web application and Web API service, how to publish it and how to implement a matching Windows Phone application, fully featured with push notifications. It also guides us on configuring the mobile service with Active Directory for authentication. At the end we are shown how to build a Windows Store app to interact with our application.

Chapter 12: Preparing an Azure System for Production

The final chapter puts everything in place, explains how to setup different build configurations for different deployment environments and how to build and deliver deployment packages for Azure. At the very end we get a deployment checklist that may come in handy if ever we run into problems.

Conclusion

Overall, I enjoyed reading this book. It doesn’t cover all of Azure, but it does a very decent job in explaining how one can build a real-life application that works and handles most typical concerns, including support for mobile devices.

ASP.NET Web Forms Prompt Validator

For those still using Web Forms and Microsoft’s validation framework, like yours truly – and I know you’re out there! -, it is very easy to implement custom validation by leveraging the CustomValidator control. It allows us to specify both a client-side validation JavaScript function and a server-side validation event handler.

In the past, I had to ask for confirmation before a form was actually submitted; the native way to ask for confirmation is through the browser’s confirm function, which basically displays a user-supplied message and two buttons, OK and Cancel. I wrapped it in a custom reusable validation control, which I am providing here:

   1: [DefaultProperty("PromptMessage")]

   2: public sealed class PromptValidator : CustomValidator

   3: {

   4:     [DefaultValue("")]

   5:     public String PromptMessage { get; set; }

   6:  

   7:     protected override void OnPreRender(EventArgs e)

   8:     {

   9:         var message = String.Concat("\"", this.PromptMessage, "\"");

  10:  

  11:         if ((this.PromptMessage.Contains("{0}") == true) && (this.ControlToValidate != String.Empty))

  12:         {

  13:             message = String.Concat("String.format(\"", this.PromptMessage, "\", args.Value)");

  14:         }

  15:  

  16:         this.ClientValidationFunction = String.Concat("new Function('sender', 'args', 'args.IsValid = confirm(", message, ")')");

  17:         this.EnableClientScript = true;

  18:  

  19:         base.OnPreRender(e);

  20:     }

  21: }

A sample usage without any target control might be:

   1: <web:PromptValidator runat="server" PromptMessage="Do you want to submit your data?" ErrorMessage="!"/>

And if you want to specifically validate a control’s value:

   1: <web:PromptValidator runat="server" PromptMessage="Do you want to accept {0}?" ErrorMessage="!" ControlToValidate="text" ValidateEmptyText="true"/>

When submitting your form, you will get a confirmation prompt similar to this (Chrome):

image

Generating GDI+ Images for the Web

.NET’s Graphics Device Interface (GDI+) is Microsoft’s .NET wrapper around the native Win32 graphics API. It is used in Windows desktop applications to generate and manipulate images and graphical contexts, like those of Windows controls. It works through a set of operations like DrawString, DrawRectangle, etc, exposed by a Graphics instance, representing a graphical context and it is well known by advanced component developers. Alas, it is rarely used in web applications, because these mainly consist of HTML, but it is possible to use them. Let’s see how.

Let’s start by implementing a custom server-side control inheriting from Image:

   1: public class ServerImage: Image

   2: {

   3:     private System.Drawing.Image image;

   4:

   5:     public ServerImage()

   6:     {

   7:         this.ImageFormat = ImageFormat.Png;

   8:         this.CompositingQuality = CompositingQuality.HighQuality;

   9:         this.InterpolationMode = InterpolationMode.HighQualityBicubic;

  10:         this.Quality = 100L;

  11:         this.SmoothingMode = SmoothingMode.HighQuality;

  12:     }

  13:

  14:     public Graphics Graphics { get; private set; }

  15:

  16:     [DefaultValue(typeof(ImageFormat), "Png")]

  17:     public ImageFormat ImageFormat { get; set; }

  18:

  19:     [DefaultValue(100L)]

  20:     public Int64 Quality { get; set; }

  21:

  22:     [DefaultValue(CompositingQuality.HighQuality)]

  23:     public CompositingQuality CompositingQuality { get; set; }

  24:

  25:     [DefaultValue(InterpolationMode.HighQualityBicubic)]

  26:     public InterpolationMode InterpolationMode { get; set; }

  27:

  28:     [DefaultValue(SmoothingMode.HighQuality)]

  29:     public SmoothingMode SmoothingMode { get; set; }

  30:

  31:     protected override void OnInit(EventArgs e)

  32:     {

  33:         if ((this.Width == Unit.Empty) || (this.Height == Unit.Empty) || (this.Width.Value == 0) || (this.Height.Value == 0))

  34:         {

  35:             throw (new InvalidOperationException("Width or height are invalid."));

  36:         }

  37:

  38:         this.image = new Bitmap((Int32)this.Width.Value, (Int32)this.Height.Value);

  39:         this.Graphics = System.Drawing.Graphics.FromImage(this.image);

  40:         this.Graphics.CompositingQuality = this.CompositingQuality;

  41:         this.Graphics.InterpolationMode = this.InterpolationMode;

  42:         this.Graphics.SmoothingMode = this.SmoothingMode;

  43:

  44:         base.OnInit(e);

  45:     }

  46:

  47:     protected override void Render(HtmlTextWriter writer)

  48:     {

  49:         var builder = new StringBuilder();

  50:

  51:         using (var stream = new MemoryStream())

  52:         {

  53:             var codec = ImageCodecInfo.GetImageEncoders().Single(x => x.FormatID == this.ImageFormat.Guid);

  54:

  55:             var parameters = new EncoderParameters(1);

  56:             parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, this.Quality);

  57:

  58:             this.image.Save(stream, codec, parameters);

  59:

  60:             builder.AppendFormat("data:image/{0};base64,{1}", this.ImageFormat.ToString().ToLower(), Convert.ToBase64String(stream.ToArray()));

  61:         }

  62:

  63:         this.ImageUrl = builder.ToString();

  64:

  65:         base.Render(writer);

  66:     }

  67:

  68:     public override void Dispose()

  69:     {

  70:         this.Graphics.Dispose();

  71:         this.Graphics = null;

  72:

  73:         this.image.Dispose();

  74:         this.image = null;

  75:

  76:         base.Dispose();

  77:     }

  78: }

Basically, this control discards the ImageUrl property and replaces it with a Data URI value generated from a stored context. You need to define the image’s Width and Height and you can also optionally specify other settings such as the image’s quality percentage (Quality), compositing quality (CompositingQuality), interpolation (InterpolationMode) and smoothing modes (SmootingMode). These settings can be used to improve the outputted image quality.

Finally, you use it like this. First, declare a ServerImage control on your page:

   1: <web:ServerImage runat="server" ID="image" Width="200px" Height="100px"/>

And then draw on its Context like you would in a Windows application:

   1: protected override void OnLoad(EventArgs e)

   2: {

   3:     this.image.Graphics.DrawString("Hello, World!", new Font("Verdana", 20, FontStyle.Regular, GraphicsUnit.Pixel), new SolidBrush(Color.Blue), 0, 0);

   4:

   5:     base.OnLoad(e);

   6: }

Basically, this control discards the ImageUrl property and replaces it with a Data URI value generated from a stored context. You need to define the image’s Width and Height and you can also optionally specify other settings such as the image’s quality percentage (Quality), compositing quality (CompositingQuality), interpolation (InterpolationMode) and smoothing modes (SmootingMode). These settings can be used to improve the outputted image quality.

Finally, you use it like this. First, declare a ServerImage control on your page:

   1: <web:ServerImage runat="server" ID="image" Width="200px" Height="100px"/>

And then draw on its Context like you would in a Windows application:

   1: protected override void OnLoad(EventArgs e)

   2: {

   3:     this.image.Graphics.DrawString("Hello, World!", new Font("Verdana", 20, FontStyle.Regular, GraphicsUnit.Pixel), new SolidBrush(Color.Blue), 0, 0);

   4:

   5:     base.OnLoad(e);

   6: }

The result is this IMG tag with a Data URI content, that you can save or copy to the clipboard:

image

Pretty sleek, don’t you think? Winking smile

Conditional Content in SharePoint Markup

In SharePoint, there are several web parts that allow us to have different contents depending on some conditions:

  • LoginView (ASP.NET): allows the definition of templates per authenticated or anonymous user:
<asp:LoginView runat="server">

    <AnonymousTemplate>

        <!-- anonymous content -->

    </AnonymousTemplate>

    <LoggedInTemplate>

        <!-- authenticated content -->

    </LoggedInTemplate>

    <RoleGroups>

        <asp:RoleGroup Roles="Admin">

            <ContentTemplate>

                <!-- admin content -->

            </ContentTemplate>

        </asp:RoleGroup>

    </RoleGroups>

</asp:LoginView>

<SharePoint:SPSecurityTrimmedControl runat="server" PermissionMode="All" PermissionContext="CurrentSite" Permissions="ManageWeb">

    <!-- secure content -->

</SharePoint:SPSecurityTrimmedControl>

  • EditModePanel: for displaying contents in a web part page depending on its edit mode:
<PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Edit">

    <!-- edit content -->

</PublishingWebControls:EditModePanel>

<SharePoint:UIVersionedContent runat="server" UIVersion="4">

    <ContentTemplate>

        <!-- content for SharePoint 2010 -->

        <!-- no code is run if does not match UIVersion -->

    </ContentTemplate>

</SharePoint:UIVersionedContent>

 

 

<SharePoint:VersionedPlaceholder runat="server" UIVersion="4">

    <!-- content for SharePoint 2010 -->

    <!-- code is always run but not rendered if does not match UIVersion -->

</SharePoint:VersionedPlaceholder>

  • AuthoringContainer: displays content depending on whether the current user has write or read rights on the current page or if it has an associated list item:
<PublishingWebControls:AuthoringContainer runat="server" DisplayAudience="ReadersOnly">

    <!-- content for readers -->

</PublishingWebControls:AuthoringContainer>

<PublishingWebControls:DeviceChannelPanel runat="server" IncludedChannels="iPhone">

    <!-- content for iPhones -->

</PublishingWebControls:DeviceChannelPanel>

  • DataViewWebPart: allows the passing of parameters and the usage of XSL for rendering logic;

I imagine you are now rolling your eyes: DataViewWebPart? how come? Well, because it doesn’t need to point to a specific list or view (unlike XsltListViewWebPart), it is very useful for markup-based customizations that will only depend on parameters:

   1: <WebPartPages:DataFormWebPart runat="server" Title="Conditional Content">

   2:     <ParameterBindings>

   3:         <ParameterBinding Name="MyParameter" Location="QueryString(MyParameter)"/>

   4:     </ParameterBindings>

   5:     <XSL>

   6:         <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl asp" xmlns:asp="System.Web.UI.WebControls">                                                  

   7:             <xsl:param name="MyParameter"/>                                                                                                                                        

   8:             <xsl:template match="/">

   9:                 <asp:Label runat="server" Text="Some content, just to show ASP.NET controls inside a SharePoint DataFormWebPart"/>

  10:                 <xsl:choose>

  11:                     <xsl:when test="$MyParameter=''">

  12:                         No parameter...

  13:                     </xsl:when>

  14:                     <xsl:otherwise>

  15:                         Allright! <xsl:value-of select="$MyParameter"/>

  16:                     </xsl:otherwise>

  17:                 </xsl:choose>                                                                                                

  18:             </xsl:template>

  19:         </xsl:stylesheet>

  20:     </XSL>                                        

  21: </WebPartPages:DataFormWebPart>

You can use this technique for:

  • Including scripts and stylesheets;
  • Including server-side controls.

It’s just a matter of rolling out some XSL to the rescue!

You may be already familiar with the available parameters, but you can find the full list here: http://msdn.microsoft.com/en-us/library/office/ff630170(v=office.15).aspx.

Another SharePoint Designer-only solution that may come in handy! 😉