Categories
Azure Microsoft Web certificates

Deploying a web certificate with ARM template to an Azure resource group and retrieving certificate thumbprint

In this article we will create an ARM template that will deploy a web certificate to an Azure resource group and output the certificate thumbprint.

Adding an SSL certificate to an app with Azure App Service can be achieved via the Azure portal. When selecting SSL certificates in an App Service then Upload Certificate, you can upload a PFX Certificate File with the associated Certificate password. The certificate will then be added to the resource group and will be available to create a binding with the application.

In today’s article we will discover how to manage this operation via an Azure Resource Manager template. Our ARM template will be created in a new Azure Resource Group deployment project in Visual Studio.

 

Creation

Let’s declare the parameters of the ARM template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "certificatePrefixName": {
      "type": "string"
    },
    "certificatePfxBase64": {
      "type": "securestring"
    },
    "certificatePfxPassword": {
      "type": "securestring"
    }
  }
  ...
}
  • certificatePrefixName: a prefix for the certificate name such as the domain name associated to the certificate.
  • certificatePfxBase64: the certificate PFX file bytes converted to a base64 string.
  • certificatePfxPassword: the password associated with the certificate.

 

Now we will declare the resources of the ARM template:

{
  ...
  "variables": {
    "certificateName": "[concat(parameters('certificatePrefixName'), uniqueString(resourceGroup().id))]"
  },
  "resources": [
    {
      "apiVersion": "2015-08-01",
      "name": "[variables('certificateName')]",
      "type": "Microsoft.Web/certificates",
      "location": "[resourceGroup().location]",
      "properties": {
        "pfxBlob": "[parameters('certificatePfxBase64')]",
        "password": "[parameters('certificatePfxPassword')]"
      },
      "tags": {
        "displayName": "Certificate"
      }
    }
  ]
  ...
}

We can pay attention to two things here:

  • The certificate name is the concatenation of the prefix name and a unique string based on the resource group id. Depending on your needs you can adapt it.
  • The certificate is declared with the following type: Microsoft.Web/certificates.

  

And to finish we will output the certificate thumbprint:

{
  ...
  "outputs": {
    "certificateThumbprint": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.Web/certificates', variables('certificateName')), providers('Microsoft.Web', 'certificates').apiVersions[0]).thumbprint]"
    }
  }
}

As you can notice, we take advantage of the ARM template function providers. This function is useful to get the latest API version for a specific namespace.

 

Example of use

The ARM template is now ready, let’s open a Windows PowerShell and try it:

.\Deploy-AzureResourceGroup.ps1 -ResourceGroupName 'MyResourceGroupName' -ResourceGroupLocation 'canadaeast' -TemplateFile '.\azuredeploy.json'

...

OutputsString      :
                     Name                   Type                       Value
                     ===============        =========================  ==========
                     certificateThumbprint  String                     22XXBE10XXE5D2DBAD29DXXXX75510583XXXXXE2

If everything goes well, you should see the same kind of message as above.

 

To go further

In the template you need the certificate PFX file bytes converted to a base 64 string. Here is a simple PowerShell script that will take the file path of a PFX file and output it as base64 string in a file:

Param([string] $pfxFilePath)

$pfxFileBytes = get-content $pfxFilePath -Encoding Byte

[System.Convert]::ToBase64String($pfxFileBytes) | Out-File 'PfxFileBytes-Base64.txt'

 

Summary

We have seen how to create an ARM template that will deploy a web certificate to an Azure resource group and output the certificate thumbprint.

 

You can download the example solution here:

Download full sources

Or

Browse the GitHub repository

 

Please feel free to comment or contact me if you have any question about this article.

Categories
App Service Azure Microsoft

Adding a custom domain name to an app with ARM template in Azure App Service

In this article we will create an ARM template that will allow to add a custom domain to a web app, mobile app, or API app in Azure App Service.

With Azure App Service it’s easy to add a custom domain via the portal. Everything is well described in the Azure documentation on the Map a custom domain name to an Azure app page.

Today we will focus on creating an Azure Resource Manager template to easily add a custom domain to an app. For our ARM template to work properly, it is first required to create the DNS record and the website.

 

Creation

Let’s declare the parameters of the ARM template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "websiteName": {
      "type": "string"
    },
    "websiteCustomDomainName": {
      "type": "string"
    }
  }
  ...
}
  • websiteName: the name of the azure app service such as myappname.azurewebsites.net.
  • websiteCustomDomainName: the name of the custom domain such as mycustomdomain.com.

 

Now we will declare the resources of the ARM template:

{
  ...
  "resources": [
    {
      "apiVersion": "2015-08-01",
      "name": "[concat(parameters('websiteName'),'/',parameters('websiteCustomDomainName'))]",
      "type": "Microsoft.Web/sites/hostNameBindings",
      "location": "[resourceGroup().location]",
      "properties": {
        "domainId": null,
        "hostNameType": "Verified",
        "siteName": "parameters('websiteName')"
      }
    }
  ]
  ...
}
  • The custom domain is declared with the following type: Microsoft.Web/sites/hostNameBindings.
  • The name of the resource is a concatenation of the website name and the custom domain name.

 

Example of use

The ARM template is now ready, let’s open a Windows PowerShell and try it:

.\Deploy-AzureResourceGroup.ps1 -ResourceGroupName 'MyResourceGroupName' -ResourceGroupLocation 'canadaeast' -TemplateFile '.\azuredeploy.json'

...

Resource Microsoft.Web/sites/hostNameBindings 'myappname/mycustomdomain.com' provisioning status is succeeded

If everything goes well, you should see the same kind of message as above.

 

To go further

If the DNS record is not created when deploying the template you’ll get the following error message:

A CNAME record pointing from mycustomdomain.com to myappname.azurewebsites.net was not found. Alternative record awverify.mycustomdomain.com to awverify.myappname.azurewebsites.net was not found either.

 

Summary

We have seen how to create an ARM template that will add a custom domain in Azure App Service.

 

You can download the example solution here:

Download full sources

Or

Browse the GitHub repository

 

Please feel free to comment or contact me if you have any question about this article.

Categories
Azure Microsoft Notification Hubs

Deploying Azure Notification Hub with ARM template and retrieving primary connection string

In this article we will create an ARM template that will deploy a Notification Hub and output the primary connection string.

Sending push notifications to your mobile application can require a lot of development and maintenance. Fortunately in all the Azure products, one will help you to send push notifications cross-platform with minimum efforts: Azure Notification Hubs.

Today we will focus on creating an Azure Resource Manager template to easily setup and deploy a Notification Hub to a resource group. Our ARM template will be created in a new Azure Resource Group deployment project in Visual Studio.

 

Creation

Let’s declare the parameters of the ARM template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "notificationHubNamespaceName": {
      "type": "string",
      "defaultValue": "[concat('myNotifHubNs', uniqueString(resourceGroup().id))]"
    },
    "notificationHubName": {
      "type": "string",
      "defaultValue": "[concat('myNotifHub', uniqueString(resourceGroup().id))]"
    },
    "notificationHubSkuName": {
      "type": "string",
      "defaultValue": "free",
      "allowedValues": [
        "free",
        "basic",
        "standard"
      ]
    }
  }
  ...
}
  • notificationHubNamespaceName: the name of the Notification Hub namespace. If no parameter is provided a default name such as myNotifHubNsesf262thj4rr6 is generated.
  • notificationHubName: the name of the Notification Hub. If no parameter is provided a default name such as myNotifHubesf262thj4rr6 is generated.
  • notificationHubSkuName: the pricing tier of the Notification Hub. If no parameter is provided the pricing tier will be free.

 

Now we will declare the resources composed by the Notification Hub namespace and the Notification Hub:

{
  ...
  "resources": [
    {
      "apiVersion": "2014-09-01",
      "name": "[parameters('notificationHubNamespaceName')]",
      "type": "Microsoft.NotificationHubs/namespaces",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "[parameters('notificationHubSkuName')]"
      },
      "properties": {
        "name": "[parameters('notificationHubNamespaceName')]",
        "namespaceType": "NotificationHub"
      },
      "resources": [
        {
          "apiVersion": "2014-09-01",
          "name": "[concat(parameters('notificationHubNamespaceName'),'/',parameters('notificationHubName'))]",
          "type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
          "location": "[resourceGroup().location]",
          "dependsOn": [
            "[concat('Microsoft.NotificationHubs/namespaces/', parameters('notificationHubNamespaceName'))]"
          ],
          "properties": {
            "name": "[parameters('notificationHubName')]"
          },
          "tags": {
            "displayName": "NotificationHub"
          }
        }
      ],
      "tags": {
        "displayName": "NotificationHubNamespace"
      }
    }
  ]
  ...
}

We can pay attention to several things here:

  • The namespace is declared with the following type: Microsoft.NotificationHubs/namespaces.
  • The hub is declared with the following type: Microsoft.NotificationHubs/namespaces/notificationHubs.
  • The hub depends on the namespace as hubs are always declared under a namespace.

 

And to finish, we will output the primary connection string of the hub: 

{
  ...
  "outputs": {
    "NotificationHubNamespaceConnectionString": {
      "type": "string",
      "value": "[listKeys(resourceId('Microsoft.NotificationHubs/namespaces/notificationHubs/authorizationRules', parameters('notificationHubNamespaceName'), parameters('notificationHubName'), 'DefaultFullSharedAccessSignature'), providers('Microsoft.NotificationHubs', 'namespaces/notificationHubs').apiVersions[0]).primaryConnectionString]"
    }
  }
}

As you can notice, we take advantage of the ARM template function listKeys and the ARM template function providers.

The function providers is useful to get the latest API version for a specific namespace, whereas listkeys is the function that will allow us to get the properties for a specific key name.

By default when a new hub is created, two access keys are created: DefaultListenSharedAccessSignature and DefaultFullSharedAccessSignature. In our template we retrieve the primary connection string for the second one.

 

Example of use

The ARM template is now ready, let’s open a Windows PowerShell and try it:

.\Deploy-AzureResourceGroup.ps1 -ResourceGroupName 'MyResourceGroupName' -ResourceGroupLocation 'canadaeast' -TemplateFile '.\azuredeploy.json'

...

OutputsString      :
                     Name                                      Type                       Value
                     ===============                           =========================  ==========
                     notificationHubNamespaceConnectionString  String                     Endpoint=sb://mynotifhubnsjibxupcseloca.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=b0zOZuqc/mvrcLq8M49mfLomHBw4PH56uazMM/8r22Q=

If everything goes well, you should see the same kind of message as above.

 

To go further

In the template we are outputting the connection string as an example. But in a more advance scenario with a Website you could directly set the application setting that require the connection string like the following:

{
  ...
  "resources": [
    {
      ...
      "resources": [
        {
          "apiVersion": "2015-08-01",
          "name": "appsettings",
          "type": "config",
          "dependsOn": [
            "[resourceId('Microsoft.NotificationHubs/namespaces/notificationHubs', parameters('notificationHubNamespaceName'), parameters('notificationHubName'))]",
            "[resourceId('Microsoft.Web/sites', parameters('myWebsiteName'))]"
          ],
          "properties": {
            "NotificationHubConnectionString": "[listKeys(resourceId('Microsoft.NotificationHubs/namespaces/notificationHubs/authorizationRules', parameters('notificationHubNamespaceName'), parameters('notificationHubName'), 'DefaultFullSharedAccessSignature'), providers('Microsoft.NotificationHubs', 'namespaces/notificationHubs').apiVersions[0]).primaryConnectionString]",
            "NotificationHubPath": "[parameters('notificationHubName')]"
          }
        }
      ]
      ...
    }
  ]
  ...
}

 

Summary

We have seen how to create an ARM template that will deploy an Azure Notification Hub and output the primary connection string.

 

You can download the example solution here:

Download full sources

Or

Browse the GitHub repository

 

Please feel free to comment or contact me if you have any question about this article.

Categories
App Service Azure Microsoft WebJobs

Implementing Dependency Injection and Dependency Scope per job in Azure WebJobs with Unity

In this article we will discover in a simple scenario how to use Unity in a Microsoft Azure WebJob.

In a previous article we discovered in a simple scenario how to use Unity in a Microsoft Azure WebJob by creating a custom IJobActivator.

Continuing this article, today we will answer the following question:

How can I get a dependency scope only for the lifetime of my function?

This question might come up for example in a scenario where you need to reach a database in a function. In this kind of scenario you want to create a DbContext, query the database, close the connection, dispose all the resources properly, same as you would do in a web application with an HTTP request. Why? Because you don’t want to end up creating a DbContext per job not knowing when everything will be disposed, you want to have the control on the dependencies lifetime.

 

Creation

Let’s continue with the source code created in the previous article by creating the following interface:

using System;

namespace AzureWebJobs.JobActivatorUnity.Dependencies
{
    public interface IJobActivatorDependencyResolver : IDisposable
    {
        IJobActivatorDependencyScope BeginScope();
    }
}

 

Now we will create the Unity implementation of it:

using System;
using AzureWebJobs.JobActivatorUnity.Dependencies;
using Microsoft.Practices.Unity;

namespace AzureWebJobs.JobActivatorUnity.Unity
{
    public class UnityJobActivatorHierarchicalDependencyResolver : IJobActivatorDependencyResolver
    {
        private readonly IUnityContainer container;

        public UnityJobActivatorHierarchicalDependencyResolver(IUnityContainer container)
        {
            if (container == null) throw new ArgumentNullException("container");

            this.container = container;
        }

        public IJobActivatorDependencyScope BeginScope()
        {
            return new UnityJobActivatorHierarchicalDependencyScope(this.container);
        }

        public void Dispose()
        {
            this.container.Dispose();
        }

        private sealed class UnityJobActivatorHierarchicalDependencyScope : IJobActivatorDependencyScope
        {
            private readonly IUnityContainer container;

            public UnityJobActivatorHierarchicalDependencyScope(IUnityContainer parentContainer)
            {
                this.container = parentContainer.CreateChildContainer();
            }

            public T CreateInstance<T>()
            {
                return this.container.Resolve<T>();
            }

            public void Dispose()
            {
                this.container.Dispose();
            }
        }
    }
}

Thanks to this implementation every time a new scope is created a specific child container is created.

 

Example of use

We have created a JobActivatorDependencyResolver and we will learn how to use it.

 

First we will register it in the Unity container along with a disposable service:

using System;
using AzureWebJobs.JobActivatorUnity.Contracts;
using AzureWebJobs.JobActivatorUnity.Dependencies;
using AzureWebJobs.JobActivatorUnity.Services;
using AzureWebJobs.JobActivatorUnity.Unity;
using Microsoft.Practices.Unity;

namespace AzureWebJobs.JobActivatorUnity
{
    public class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Gets the configured Unity container.
        /// </summary>
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// <summary>Registers the type mappings with the Unity container.</summary>
        /// <param name="container">The unity container to configure.</param>
        public static void RegisterTypes(IUnityContainer container)
        {
            container.RegisterType<IJobActivatorDependencyResolver, UnityJobActivatorHierarchicalDependencyResolver>(new ContainerControlledLifetimeManager(), new InjectionConstructor(container.CreateChildContainer()));
            container.RegisterType<INumberService, NumberService>(new ContainerControlledLifetimeManager());
            container.RegisterType<IUnitOfWork, DisposableService>(new HierarchicalLifetimeManager());
        }
    }
}

You can notice two elements here:

  • We configure the dependency resolver to be a singleton.
  • We provide the dependency resolver with its own child container. All the scopes created will be under this container.

 

In our job function we can now use the IJobActivatorDependencyResolver:

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using AzureWebJobs.JobActivatorUnity.Contracts;
using AzureWebJobs.JobActivatorUnity.Dependencies;
using Microsoft.Azure.WebJobs;

namespace AzureWebJobs.JobActivatorUnity
{
    public class Functions
    {
        private readonly IJobActivatorDependencyResolver jobActivatorDependencyResolver;
        private readonly INumberService numberService;

        public Functions(IJobActivatorDependencyResolver jobActivatorDependencyResolver, INumberService numberService)
        {
            if (jobActivatorDependencyResolver == null) throw new ArgumentNullException("jobActivatorDependencyResolver");
            if (numberService == null) throw new ArgumentNullException("numberService");

            this.jobActivatorDependencyResolver = jobActivatorDependencyResolver;
            this.numberService = numberService;
        }

        // This function will get triggered/executed when a new message is written 
        // on an Azure Queue called queue.
        public async Task ProcessQueueMessage([QueueTrigger("queue")] string message, TextWriter log, CancellationToken ct)
        {
            log.WriteLine("New random number {0} from shared number service for message: {1}", this.numberService.GetRandomNumber(), message);

            using (var scope = this.jobActivatorDependencyResolver.BeginScope())
            {
                Console.WriteLine("Beginning scope work...");

                log.WriteLine("New random number {0} from scoped number service for message: {1}", scope.CreateInstance<INumberService>().GetRandomNumber(), message);

                await scope.CreateInstance<IUnitOfWork>().DoWork(ct, message);

                Console.WriteLine("Finishing scope work...");
            }
        }
    }
}

We can pay attention to several things here:

  • An INumberService instance is injected in our function and shared among jobs.
  • We also demonstrate the possibility to create a specific instance of INumberService for the scope.
  • The IUnitOfWork DoWork call could typically be a work against a database.
  • All the instances created inside the scope will be disposed immediately before the function ends.

 

To go further

If you test the source code, the console output will be the following when the function is triggered:

Executing: 'Functions.ProcessQueueMessage' - Reason: 'New queue message detected on 'queue'.'
Beginning scope work...
DisposableService doing work...
Finishing scope work...
DisposableService disposing...
Executed: 'Functions.ProcessQueueMessage' (Succeeded)

 

Summary

We have seen how to create a Dependency Scope in a Microsoft Azure WebJob function in a more advanced scenario which completes the previous article.

Now in the scenario we just covered there is place for improvement. Instead of calling a CreateInstance<T>() every time we need an object, we could simplify it by creating job handlers.

This will be the subject of the last article in the series about Dependency Injection in Azure WebJobs, stay tuned!

 

You can download the example solution here:

Download full sources

Or

Browse the GitHub repository

(Note that the project uses Microsoft.Azure.WebJobs version 1.1.2)

 

Please feel free to comment or contact me if you have any question about this article.

Categories
Azure Microsoft Storage Table

Executing an async query with Azure Table storage and retrieve all the results in a single operation

A useful TableQuery extension to retrieve all the results of a Microsoft Azure Table storage in a single asynchronous operation.

In the Azure Storage client library that you use to work with Azure Table storage, you may have notice that nothing will allow you to retrieve asynchronously all the results of a query in a single operation and that’s probably what brought you here.

 

If you take a look at TableQuery<TElement> you will find two methods:

  • Execute: synchronously executes a query on a table.
  • ExecuteSegmentedAsync: asynchronously executes a query on a table and return segmented results.

Same goes for CloudTable:

  • ExecuteQuery<TElement>: synchronously executes a query on a table.
  • ExecuteQuerySegmentedAsync<TElement>: asynchronously executes a query on a table and return segmented results.

The legitimate question for you to ask is where are the methods ExecuteAsync and ExecuteQueryAsync?

Well those methods are not available in the library. If you want to get all the results of a query in one shot your only choice is to do so synchronously. If you want to get all the results in an async way, you will have to work with segmented results.

In many case asynchronously working with segmented results is the best option and that’s probably why the Azure team built it this way. Working with segments is great, especially when you have a lot of records because you don’t have to wait for all the results to start processing them, think parallel processing.

But in some case you want to get all the results before processing them, and if you are in an async context the following extension may help you.

 

Creation

In my scenario I know I’ll always work in a small set of records, I’m in an async context and I need to get all the results before processing them.

The ExecuteAsync TableQuery extension looks like the following:

using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.Queryable;

namespace AzureTableStorage.TableQueryAsync
{
    public static class TableQueryExtensions
    {
        /// <summary>
        /// Initiates an asynchronous operation to execute a query and return all the results.
        /// </summary>
        /// <param name="tableQuery">A Microsoft.WindowsAzure.Storage.Table.TableQuery representing the query to execute.</param>
        /// <param name="ct">A System.Threading.CancellationToken to observe while waiting for a task to complete.</param>
        public async static Task<IEnumerable<TElement>> ExecuteAsync<TElement>(this TableQuery<TElement> tableQuery, CancellationToken ct)
        {
            var nextQuery = tableQuery;
            var continuationToken = default(TableContinuationToken);
            var results = new List<TElement>();

            do
            {
                //Execute the next query segment async.
                var queryResult = await nextQuery.ExecuteSegmentedAsync(continuationToken, ct);

                //Set exact results list capacity with result count.
                results.Capacity += queryResult.Results.Count;

                //Add segment results to results list.
                results.AddRange(queryResult.Results);

                continuationToken = queryResult.ContinuationToken;

                //Continuation token is not null, more records to load.
                if (continuationToken != null && tableQuery.TakeCount.HasValue)
                {
                    //Query has a take count, calculate the remaining number of items to load.
                    var itemsToLoad = tableQuery.TakeCount.Value - results.Count;

                    //If more items to load, update query take count, or else set next query to null.
                    nextQuery = itemsToLoad > 0
                        ? tableQuery.Take<TElement>(itemsToLoad).AsTableQuery()
                        : null;
                }

            } while (continuationToken != null && nextQuery != null && !ct.IsCancellationRequested);

            return results;
        }
    }
}

We can pay attention to two things here:

  • We are using TableContinuationToken. It is the usual way to do when working with segments.
  • This token will let us know if more results are available or else it will be null.

As you can notice the extension is simple, however the trickiest part comes when a TableQuery has the TakeCount property set. In that case we need to reevaluate the number of items to take after each segment results.

 

Example of use

Here is a quick example showing how to use the extension in a console application:

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.Queryable;

namespace AzureTableStorage.TableQueryAsync
{
    class Program
    {
        static void Main(string[] args)
        {
            ExecuteSimpleTableQuery(CancellationToken.None).Wait();

            Console.ReadLine();
        }

        private static async Task ExecuteSimpleTableQuery(CancellationToken ct)
        {
            var table = await GetTable(ct);

            var query = table.CreateQuery<MyTableEntity>()
                .Where(r => !r.MyProperty.Equals(string.Empty))
                .Take(1200)
                .AsTableQuery();

            var results = await query.ExecuteAsync(ct);

            Console.WriteLine($"Results {(results.Any() ? string.Empty : "not ")}found.");
        }

        private static async Task<CloudTable> GetTable(CancellationToken ct)
        {
            //Retrieve the storage account from the connection string.
            var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));

            //Create the table client.
            var tableClient = storageAccount.CreateCloudTableClient();

            //Retrieve a reference to the table.
            var table = tableClient.GetTableReference("mystoragetable");

            //Create the table if it doesn't exist.
            await table.CreateIfNotExistsAsync(ct);

            return table;
        }
    }
}

This TableQuery will let us get 1200 results asynchronously with entities having the property MyProperty not empty.

 

To go further

When a segmented query is executed a maximum of 1,000 entries is returned. If the value specified for the TableQuery TakeCount property is greater than 1,000, the library will ignore it and limit it to 1,000.

 

Summary

Thanks to this extension we have seen how to retrieve all the results of a Microsoft Azure Table storage in a single asynchronous operation. Of course I advise you to use it wisely, in scenarios where you specifically need to get all the results before processing them, for other scenarios you should stick to the segmented query.

 

You can download the example solution here:

Download full sources

Or

Browse the GitHub repository

(Note that the project uses WindowsAzure.Storage version 7.2.1)

 

Please feel free to comment or contact me if you have any question about this article.

Categories
App Service Azure Microsoft WebJobs

How to use Unity as job activator and implement Dependency Injection in Azure WebJobs

In this article we will discover in a simple scenario how to use Unity in a Microsoft Azure WebJob.

If you are a user of Azure App Service you are probably aware of the Azure WebJobs. If it’s not case the case, I advise you to take a look at it because Azure WebJobs are very powerful to run background processes and comes at no extra cost when already using Azure App Service (Web Apps, Mobile Apps, API Apps, Logic Apps).

Also Azure WebJobs come along the Azure WebJobs SDK that has a great trigger system to work with Azure Storage. For example a job function can be automatically started when a message is inserted into an Azure Queue storage.

Behind the scene the trigger system will create a new instance of the class containing the function, then the function will be invoked. The responsibility of creating instances of job classes is given to the JobActivator.

 

DefaultJobActivator

Now let’s take a look at the original source code of the DefaultJobActivator on GitHub:

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;

namespace Microsoft.Azure.WebJobs.Host.Executors
{
    internal class DefaultJobActivator : IJobActivator
    {
        private static readonly DefaultJobActivator Singleton = new DefaultJobActivator();

        private DefaultJobActivator()
        {
        }

        public static DefaultJobActivator Instance
        {
            get { return Singleton; }
        }

        public T CreateInstance<T>()
        {
            return Activator.CreateInstance<T>();
        }
    }
}

Here you can notice two things:

  • Activator.CreateInstance<T>() is used to create an instance of the specified type.
  • DefaultJobActivator implements IJobActivator.

The problem with this implementation is that only an instance of a job class with parameterless constructor can be created.

 

Fortunately for us the Azure WebJobs SDK allows to specify a custom JobActivator in the JobHostConfiguration.

In the original source code on GitHub we can see that the DefaultJobActivator is used when creating a new JobHostConfiguration:

AddService<IJobActivator>(DefaultJobActivator.Instance);

Now let’s take a look at how to replace the default job activator with our own using Unity!

 

Creation

For our needs we will create the following interface inheriting from IJobActivator:

using System;
using Microsoft.Azure.WebJobs.Host;

namespace AzureWebJobs.JobActivatorUnity.Dependencies
{
    public interface IJobActivatorDependencyScope : IJobActivator, IDisposable
    {
    }
}

 

Now we will create the Unity implementation of it:

using System;
using AzureWebJobs.JobActivatorUnity.Dependencies;
using Microsoft.Practices.Unity;

namespace AzureWebJobs.JobActivatorUnity.Unity
{
    public class UnityJobActivatorDependencyScope : IJobActivatorDependencyScope
    {
        private readonly IUnityContainer container;

        public UnityJobActivatorDependencyScope(IUnityContainer container)
        {
            if (container == null) throw new ArgumentNullException("container");

            this.container = container;
        }

        public T CreateInstance<T>()
        {
            return this.container.Resolve<T>();
        }

        public void Dispose()
        {
            this.container.Dispose();
        }
    }
}

Thanks to this implementation the responsibility of creating instances is given to the Unity container through the invocation of container.Resolve<T>().

 

Example of use

We have created a custom JobActivator, now we will learn how to use it in a simple scenario.

 

First we will configure the Unity container and register a simple service to it:

using System;
using AzureWebJobs.JobActivatorUnity.Contracts;
using AzureWebJobs.JobActivatorUnity.Services;
using Microsoft.Practices.Unity;

namespace AzureWebJobs.JobActivatorUnity
{
    public class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Gets the configured Unity container.
        /// </summary>
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// <summary>Registers the type mappings with the Unity container.</summary>
        /// <param name="container">The unity container to configure.</param>
        public static void RegisterTypes(IUnityContainer container)
        {
            container.RegisterType<INumberService, NumberService>(new ContainerControlledLifetimeManager());
        }
    }
}

Here nothing special as it’s a common Unity container configuration. The INumberService is used for the example and will allow us to return a random number.

 

Now we will configure our WebJob to use our custom IJobActivator:

using AzureWebJobs.JobActivatorUnity.Unity;
using Microsoft.Azure.WebJobs;

namespace AzureWebJobs.JobActivatorUnity
{
    // To learn more about Microsoft Azure WebJobs SDK, please see http://go.microsoft.com/fwlink/?LinkID=320976
    class Program
    {
        // Please set the following connection strings in app.config for this WebJob to run:
        // AzureWebJobsDashboard and AzureWebJobsStorage
        static void Main()
        {
            var config = new JobHostConfiguration()
            {
                JobActivator = new UnityJobActivatorDependencyScope(UnityConfig.GetConfiguredContainer())
            };

            var host = new JobHost(config);
            // The following code ensures that the WebJob will be running continuously
            host.RunAndBlock();
        }
    }
}

 

In our job function we use can now use the INumberService:

using System;
using System.IO;
using AzureWebJobs.JobActivatorUnity.Contracts;
using Microsoft.Azure.WebJobs;

namespace AzureWebJobs.JobActivatorUnity
{
    public class Functions
    {
        private readonly INumberService numberService;

        public Functions(INumberService numberService)
        {
            if (numberService == null) throw new ArgumentNullException("numberService");

            this.numberService = numberService;
        }

        // This function will get triggered/executed when a new message is written 
        // on an Azure Queue called queue.
        public void ProcessQueueMessage([QueueTrigger("queue")] string message, TextWriter log)
        {
            log.WriteLine("New random number {0} for message: {1}", this.numberService.GetRandomNumber(), message);
        }
    }
}

We can pay attention to several things here:

  • The INumberService is automatically injected in our function thanks to the Unity container.
  • When the ProcessQueueMessage function is triggered by the QueueTrigger we can seamlessly use the number service.
  • We could easily add other dependencies to the function.

 

To go further

When a function is triggered by the Azure WebJobs trigger system it is interesting to understand that a new instance of the class containing the function is created via the IJobActivator before invoking the function itself. This is important because every time a function is triggered it gives you latitude on the configuration of the dependencies’ lifetime.

 

Summary

We have seen how to use Unity as job activator and implement IoC and DI in a Microsoft Azure WebJob simple scenario.

Of course instead of using Unity you are free to use another IoC container like Autofac, Ninject, Simple Injector, etc.

 

Now in the scenario we just went through you may have asked yourself: “But how can I get a dependency scope only for the lifetime of my function?”.

Yes what if I want to get dependencies that will be just instantiated for my function and make sure that those resources will be disposed when the function’s job is done. Like reaching a database for the purpose of the function and close the connection, dispose all the resources properly. Well that will be the subject of my next article about Azure WebJobs in a more complex scenario, stay tuned!

 

You can download the example solution here:

Download full sources

Or

Browse the GitHub repository

(Note that the project uses Microsoft.Azure.WebJobs version 1.1.2)

 

Please feel free to comment or contact me if you have any question about this article.

Categories
Personal thoughts

Passed Exam 70-486: Developing ASP.NET MVC Web Applications

After years developing with ASP.NET MVC I finally made the jump.

This may seem weird for some of you but I have never tried to take the ASP.NET MVC exam although I’ve developed several applications both personally and professionally, this very same website was built with it and I have published several articles on it.

 

Why not before?

To be honest I have never been comfortable with certifications, I don’t want to learn by heart or use brain dumps. What I like is to learn by doing, problem is it takes time.

My journey with ASP.NET MVC started 7 years ago, summer 2009, with ASP.NET MVC 1.0. Since then I went through all the versions on various projects.

By the way ASP.NET MVC 3 was the real usable version!

 

So why passing Exam 70-486 only now?

  • It is out since October 2012, the pool of questions is robust
  • It is up to date with ASP.NET MVC 5
  • I wanted to challenge myself, after all those years I was supposed be a good candidate
  • It is not planned to be retired

The most important point for me is the last one, because I didn’t want to pass an exam knowing it will be retired shortly.

For now, it is not planned to be retired and don’t think it will be retired soon. Sure it will be updated but I don’t think it will be retired.

Also now it is included in ASP.NET Core and is 90% identical to the original.

Considering all this we can see long-term and I consider this exam as a good investment (time/money) because you are not going to lose all your knowledge tomorrow.

 

Passing the exam and result

I bought the Microsoft Certification Booster Pack (exam + 4 retakes) and I scheduled an online proctored exam.

I did not study before the exam and all those years developing with ASP.NET MVC paid off.

After two and an half hours I successfully passed the exam at the first shot! All the questions made sense, case studies were interesting. Yes as often there are some tricky questions but overall it has been a great way to validate my knowledge, it is very satisfying.

 

Also it was my first online exam, it is convenient to schedule after work at 6pm and pass it at home. However it is very serious, and the work-area scan by the greeter was pretty epic!

 

Final thought

I’m glad I did the move, it is rewarding. So if you are in a situation similar to mine I encourage you to go ahead and validate your knowledge.

 

Please feel free to comment or contact me if you have any question. Of course don’t ask me about to the content of the exam, as you know Non-Disclosure Agreement apply for Microsoft Certification Exams.

Categories
Microsoft Windows Phone 7

How to get your Windows Phone 7 application id directly in your application

So that you don’t need to submit your application to get it’s id and resubmit it.

For my future WP7 application Warnygo, I needed to get its id for several reasons. For example, use it with the ShareLinkTask or send it to my services.

As you may know, you can find your application id in the WMAppManifest.xml. It’s the ProductID attribute in the App node.

When you first create your application with Visual Studio, you get a random one. But you will get a new one through the marketplace submission process. So how to get your application id in your application once submitted?

 

Well, the ugly way is to:

  • Submit your application to the marketplace so that you can get the real application id.
  • Then update your application with the new application id wherever you need it.
  • To finish resubmit your application.

 

Personally I don’t like this way!

 

The clean way that I propose is to directly read the application id in the WMAppManifest.xml file. Check this code:

using System;
using System.Xml.Linq;

namespace PhoneApp.ApplicationId
{
    public static class ApplicationProperties
    {
        public static Guid GetId()
        {
            Guid applicationId = Guid.Empty;

            var productId = XDocument.Load("WMAppManifest.xml").Root.Element("App").Attribute("ProductID");

            if (productId != null && !string.IsNullOrEmpty(productId.Value))
                Guid.TryParse(productId.Value, out applicationId);

            return applicationId;
        }
    }
}

 

Example of use

using System;
using System.Windows;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Tasks;

namespace PhoneApp.ApplicationId
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void ButtonShowId_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(ApplicationProperties.GetId().ToString(), "My id is:", MessageBoxButton.OK);
        }

        private void ButtonShare_Click(object sender, RoutedEventArgs e)
        {
            ShareLinkTask shareLinkTask = new ShareLinkTask();
            shareLinkTask.Title = "Check this app!";
            shareLinkTask.LinkUri = new Uri(string.Format("http://www.windowsphone.com/s?appid={0}", ApplicationProperties.GetId()), UriKind.Absolute);
            shareLinkTask.Show();
        }
    }
}

 

Summary

We have seen how to get a Windows Phone 7 Application id. If like me you have your own WP7 framework, you should add this extension!

 

You can download the example solution here:

Download full sources

 

(Note that the project uses the Windows Phone SDK 7.1)

 

As usual, if you have any questions about this article please feel free to contact me or leave a comment in the section bellow.

Categories
Microsoft Windows Phone 7

Navigate from one view to another passing a complex object parameter without specifying the target view Uri in a Windows Phone 7 Application

A looooong title for a recurring question when you start developping a Windows Phone 7 Application.

It’s been a while since my last article (April 21, 2011! Wo!), but time is running so fast and I was very busy with several projects.

One of these was real live tracking in rally with WP7 and Bing Maps for the International Rally of Burgundy. See WP7 for tracking in Rallye on WPCentral for more details.

 

So go back to the subject of this article. I recently restarted the development of a WP7 application named Warnygo from scratch with Mango tools and I faced the same questions.

 

Reminder about NavigationService

As you know when you want to navigate from one view to another, you use the NavigationService like that:

NavigationService.Navigate(new Uri(“/View/MyPage.xaml?msg=hello”UriKind.Relative));

In the target view, in the OnNavigatedTo method you use the NavigationContext to get your paremeter(s):

string msg = string.Empty; NavigationContext.QueryString.TryGetValue(“msg”out msg))

 

Questions about the NavigationService

So this was the standard use of the NavigationService. There are two things I dislike here:

  • I need to write the target view Uri every time I need to navigate to it. So one solution would be to write this uri in a static variable.
  • I can’t pass a complex parameter to my target view. I’m stuck with the NavigationContext QueryString.

Two questions comes here:

  • Can we navigate to a view without specifying its Uri every time?
  • Can we navigate to a view passing a complex parameter?

The answer in image:

I must admit that I had prepared this one, but it was too tempting 🙂

 

Creation

For our needs we will create two interfaces to manage navigation with complex parameters:

namespace PhoneApp.NavigateToView.Core.Views
{
    public interface IView
    {
    }

    public interface IView<ViewNavigationParametersType> : IView
    {
        ViewNavigationParametersType NavigationParameters { get; set; }
    }
}

 

To navigate to a view without specifying the target view Uri, the trick is to create a custom attribute that we will use to decorate our views:

using System;

namespace PhoneApp.NavigateToView.Core.Views
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
    public sealed class ViewInfosAttribute : Attribute
    {
        private readonly Uri uriString;

        public ViewInfosAttribute(string uriString, UriKind uriKind = UriKind.Relative)
        {
            this.uriString = new Uri(uriString, uriKind);
        }

        public Uri Uri
        {
            get { return uriString; }
        }
    }
}

 

Now we need to create two NavigationService extensions to manager this new kind of navigation:

using System.Windows.Navigation;
using PhoneApp.NavigateToView.Core.Views;

namespace PhoneApp.NavigateToView.Core.Navigation
{
    public static class NavigationServiceExtensions
    {
        public static void NavigateToView<IView>(this NavigationService navigationService) where IView : Views.IView
        {
            Views.ViewInfosAttribute[] viewInfosAttribute = (Views.ViewInfosAttribute[])typeof(IView).GetCustomAttributes(typeof(Views.ViewInfosAttribute), false);
            if (viewInfosAttribute.Length == 1)
            {
                navigationService.Navigate(viewInfosAttribute[0].Uri);
            }
        }

        public static void NavigateToView<IView, ViewNavigationParametersType>(this NavigationService navigationService, ViewNavigationParametersType navigationParameters) where IView : Views.IView<ViewNavigationParametersType>
        {
            if (navigationParameters != null)
            {
                NavigatedEventHandler navigatedEventHandler = null;
                navigatedEventHandler = (s, e) =>
                {
                    ((IView<ViewNavigationParametersType>)e.Content).NavigationParameters = navigationParameters;
                    navigationService.Navigated -= navigatedEventHandler;
                };
                navigationService.Navigated += navigatedEventHandler;
                navigationService.NavigateToView<IView>();
            }
        }
    }
}

As you may notice, we are setting the view navigation parameters in the Navigated event. This event is triggered before the OnNavigatedTo in the target view.

 

Example of use

For the purposes of this article I have created a simple Windows Phone 7 solution (You can download it bellow) to show you how to use the two NavigationService extensions. In this solutions we have three views:

  • The main view
  • A product list view
  • A product details view

 

So, what looks like the main view code-behind?

using Microsoft.Phone.Controls;
using PhoneApp.NavigateToView.Core.Navigation;
using PhoneApp.NavigateToView.Core.Views;
using PhoneApp.NavigateToView.Views.Products;

namespace PhoneApp.NavigateToView.Views
{
    [ViewInfos("/Views/MainView.xaml")]
    public partial class MainView : PhoneApplicationPage, IView
    {
        public MainView()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            this.NavigationService.NavigateToView<ProductListView>();
        }
    }
}

As you see the view is decorated with our custom attribute named ViewInfos where we specify the view path.

When we click on the Navigate to products button we are calling the first NavigationService extension, because we simply need to navigate to the product list view, without parameters.

 

On the other hand, in the product list view we need to pass the selected product to the product details view.

Here is the product list view code-behind:

using System.Collections.ObjectModel;
using Microsoft.Phone.Controls;
using PhoneApp.NavigateToView.Core.Navigation;
using PhoneApp.NavigateToView.Core.Views;
using PhoneApp.NavigateToView.Models;
using PhoneApp.NavigateToView.Models.NavigationParameters.Products;

namespace PhoneApp.NavigateToView.Views.Products
{
    [ViewInfos("/Views/Products/ProductListView.xaml")]
    public partial class ProductListView : PhoneApplicationPage, IView
    {
        private ObservableCollection<Product> products;

        public ProductListView()
        {
            InitializeComponent();
            this.LoadProducts();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            this.DataContext = this.products;
        }

        private void ProductsListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (ProductListBox.SelectedIndex == -1)
                return;
            this.NavigationService.NavigateToView<ProductEditView, EditProductParameters>(new EditProductParameters { Mode = EditProductMode.Edit, Product = ProductListBox.SelectedItem as Product });

            ProductListBox.SelectedIndex = -1;
        }

        private void ApplicationBarIconButton_Click(object sender, System.EventArgs e)
        {
            this.NavigationService.NavigateToView<ProductEditView, EditProductParameters>(new EditProductParameters { Mode = EditProductMode.Create });
        }

        private void LoadProducts()
        {
            this.products = new ObservableCollection<Product>();
            for (int i = 1; i < 51; i++)
            {
                products.Add(new Product
                {
                    Id = i,
                    Name = "Product " + i,
                    Description = "Product description " + i
                });
            }
        }
    }
}

 

We are navigating to the product details view when the application bar button is clicked or when a product is selected. We specify that the navigation parameters type is EditProductParameters.

We can then use the navigation parameters in the product details view:

using Microsoft.Phone.Controls;
using PhoneApp.NavigateToView.Core.Views;
using PhoneApp.NavigateToView.Models;
using PhoneApp.NavigateToView.Models.NavigationParameters.Products;

namespace PhoneApp.NavigateToView.Views.Products
{
    [ViewInfos("/Views/Products/ProductEditView.xaml")]
    public partial class ProductEditView : PhoneApplicationPage, IView<EditProductParameters>
    {
        private EditProductParameters navigationParameters;
        public EditProductParameters NavigationParameters
        {
            get
            {
                return this.navigationParameters;
            }
            set
            {
                this.navigationParameters = value;
            }
        }

        public ProductEditView()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            switch (this.NavigationParameters.Mode)
            {
                case EditProductMode.Create:
                    this.DataContext = new Product { Name = "New product", Description = "New product description" };
                    break;
                case EditProductMode.Edit:
                    this.DataContext = this.NavigationParameters.Product;
                    break;
            }
        }
    }
}

 

To go further

To make this article simple I didn’t use MVVM pattern. In fact in my own WP7 framework I didn’t created those two NavigationService methods as extensions. Initially it is two methods in my ViewModelBase so I can navigate from a ViewModel to a View. All this to say that you can use those extensions even if you are developing your application using MVVM pattern.

 

I’d like to add that the solution I give you here is not THE solution it is a way to answer this article main questions about the NavigationService.

 

Summary

We have seen how to Navigate from one view to another passing a complex object parameter without specifying the target view Uri in a Windows Phone 7 Application.

Isn’t that cool?! I mean, supposing that you are developer of course, because if you’re not you don’t give a sh** about that! 🙂

No, to be serious our code is way cleaner like that, isn’t it?

 

You can download the example solution here:

Download full sources

(Note that the project uses the Windows Phone SDK 7.1 Release Candidate)

As usual, if you have any questions about this article please feel free to contact me or leave a comment in the section bellow.

 

Super bonus of the day: Bindable ApplicationBar

Have you ever tried to bind the standard application bar? If yes, you know that unfortunately the standard application bar is not bindable…

 

But wait! Don’t leave already!

The good new is that one of my colleague and friend Nicolas Humann has created a Bindable ApplicationBar just for you lucky guys

And he has updated it to work with Mango!

 

Do no wait, check his website: http://blog.humann.info/

Categories
ASP.NET ASP.NET MVC Microsoft

Create an authorized action link extension for ASP.NET MVC 3

In this article I will explain how to create an action link extension that is authorizations aware, so that we can hide or disable an action link based on its authorizations.

When you create a website with multiple permissions, it would be nice to display action links depending on those permissions. For example if your website contains a menu, its better to display links according to the permissions. You don’t want your users to click on a link, and then display an unauthorized access message.

 

With ASP.NET MVC, we can easily create an action link that is authorizations aware. It will be above the standard action link.

Important: note that the code below is only for ASP.NET MVC 3. It’s because there has been some changes with filters since ASP.NET MVC 2.

 

 Creation

First we will create an extension that will allow us to know if an action is authorized:

using System.Web.Mvc;

namespace MvcApplication.AuthorizedActionLink.Extensions
{
	public static class ActionExtensions
	{
		public static bool ActionAuthorized(this HtmlHelper htmlHelper, string actionName, string controllerName)
		{
			ControllerBase controllerBase = string.IsNullOrEmpty(controllerName) ? htmlHelper.ViewContext.Controller : htmlHelper.GetControllerByName(controllerName);
			ControllerContext controllerContext = new ControllerContext(htmlHelper.ViewContext.RequestContext, controllerBase);
			ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerContext.Controller.GetType());
			ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);

			if (actionDescriptor == null)
				return false;

			FilterInfo filters = new FilterInfo(FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor));

			AuthorizationContext authorizationContext = new AuthorizationContext(controllerContext, actionDescriptor);
			foreach (IAuthorizationFilter authorizationFilter in filters.AuthorizationFilters)
			{
				authorizationFilter.OnAuthorization(authorizationContext);
				if (authorizationContext.Result != null)
					return false;
			}
			return true;
		}
	}
}

As you can see we are retrieving action authorization filters. For each filter we test if the authorization context Result property is null. If this property is not null, it means that the user is not authorized to go on the action.

 

We also use an extension named GetControllerByName, in case the controller name is not specified:

using System;
using System.Globalization;
using System.Web.Mvc;

namespace MvcApplication.AuthorizedActionLink
{
	internal static class Helpers
	{
		public static ControllerBase GetControllerByName(this HtmlHelper htmlHelper, string controllerName)
		{
			IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
			IController controller = factory.CreateController(htmlHelper.ViewContext.RequestContext, controllerName);
			if (controller == null)
			{
				throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "The IControllerFactory '{0}' did not return a controller for the name '{1}'.", factory.GetType(), controllerName));
			}
			return (ControllerBase)controller;
		}
	}
}

 

Now that we are able to know if an action is authorized, we can create a new link extension named ActionLinkAuthorized so it sticks to the standard ActionLink:

using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
using MvcApplication.AuthorizedActionLink.Extensions;

namespace MvcApplication.AuthorizedActionLink.Html
{
	public static class LinkExtensions
	{
		public static MvcHtmlString ActionLinkAuthorized(this HtmlHelper htmlHelper, string linkText, string actionName, bool showActionLinkAsDisabled = false)
		{
			return htmlHelper.ActionLinkAuthorized(linkText, actionName, null, new RouteValueDictionary(), new RouteValueDictionary(), showActionLinkAsDisabled);
		}

		public static MvcHtmlString ActionLinkAuthorized(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, bool showActionLinkAsDisabled = false)
		{
			return htmlHelper.ActionLinkAuthorized(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary(), showActionLinkAsDisabled);
		}

		public static MvcHtmlString ActionLinkAuthorized(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, bool showActionLinkAsDisabled = false)
		{
			return htmlHelper.ActionLinkAuthorized(linkText, actionName, controllerName, new RouteValueDictionary(), new RouteValueDictionary(), showActionLinkAsDisabled);
		}

		public static MvcHtmlString ActionLinkAuthorized(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, bool showActionLinkAsDisabled = false)
		{
			return htmlHelper.ActionLinkAuthorized(linkText, actionName, null, routeValues, new RouteValueDictionary(), showActionLinkAsDisabled);
		}

		public static MvcHtmlString ActionLinkAuthorized(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes, bool showActionLinkAsDisabled = false)
		{
			return htmlHelper.ActionLinkAuthorized(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes), showActionLinkAsDisabled);
		}

		public static MvcHtmlString ActionLinkAuthorized(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes, bool showActionLinkAsDisabled = false)
		{
			return htmlHelper.ActionLinkAuthorized(linkText, actionName, null, routeValues, htmlAttributes, showActionLinkAsDisabled);
		}

		public static MvcHtmlString ActionLinkAuthorized(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes, bool showActionLinkAsDisabled = false)
		{
			return htmlHelper.ActionLinkAuthorized(linkText, actionName, controllerName, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes), showActionLinkAsDisabled);
		}

		public static MvcHtmlString ActionLinkAuthorized(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes, bool showActionLinkAsDisabled)
		{
			if (htmlHelper.ActionAuthorized(actionName, controllerName))
			{
				return htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
			}
			else
			{
				if (showActionLinkAsDisabled)
				{
					TagBuilder tagBuilder = new TagBuilder("span");
					tagBuilder.InnerHtml = linkText;
					return MvcHtmlString.Create(tagBuilder.ToString());
				}
				else
				{
					return MvcHtmlString.Empty;
				}
			}
		}
	}
}

 

Example of use

Let’s say we want to authorize only users with role Administrator on the HomeController action named ThePrivilegeZone. ThePrivilegeZone action will be decorated with an authorize attribute. We add a link to this action in the site menu with the authorized action link extension specifying that we want to show the  action link as disabled if the user is not authorized:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<%@ Import Namespace="MvcApplication.AuthorizedActionLink.Html" %>

<!DOCTYPE html>
<html>
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
    <script src="<%: Url.Content("~/Scripts/jquery-1.4.4.min.js") %>" type="text/javascript"></script>
</head>

<body>
    <div class="page">

        <div id="header">
            <div id="title">
                <h1>My MVC Application</h1>
            </div>
              
            <div id="logindisplay">
                <% Html.RenderPartial("LogOnUserControl"); %>
            </div> 
            
            <div id="menucontainer">
            
                <ul id="menu">              
                    <li><%: Html.ActionLink("Home", "Index", "Home")%></li>
                    <li><%: Html.ActionLink("About", "About", "Home")%></li>
                    <li><%: Html.ActionLinkAuthorized("The Privilege Zone", "ThePrivilegeZone", "Home", true)%></li>
                </ul>
            
            </div>
        </div>

        <div id="main">
            <asp:ContentPlaceHolder ID="MainContent" runat="server" />

            <div id="footer">
            </div>
        </div>
    </div>
</body>
</html>

 

The result looks like below when the user is not authorized and the action link disabled:

It would be better to add some styling 🙂

 

To go further

To be honest I didn’t invent anything here. I have just take a deep look into the ASP.NET MVC 3 source code available on the Microsoft website in order to understand how authorizations works, and I have mixed it with the standard ActionLink. My code is based on three classes: ControllerActionInvoker, MvcHandler, LinkExtensions.

 

Summary

We have seen how to create and use an authorized action link.

You can download the example solution here:

Download full sources

(Note that the project uses ASP.NET MVC 3)

 

Please feel free to comment or contact me if you have any question about this article.