ADAL at Techorama

At Techorama I gave a presentation about Active Directory Authentication Libraries (ADAL) and how you can easily use these to add authentication to your mobile apps.The session slides can be found hereADAL.pptx (1.2MB)

Excellent intro to Windows Azure

If you want an excellent introduction into Windows Azure I can recommend “Windows Azure: Step by Step” from Roberto Brunetti. This book will teach you the basic components of Windows Azure and how to build an application with them. It will introduce you to Azure Compute, Azure Storage and Azure AppFabric Servicebus; in clear and easy-to-follow step-by-step instructions you build applications that use the different Azure features. In my opinion this is the best way to learn. Unfortunately this book doesn’t have space to delve deeper into some subjects (or you would need a >1000 pages book), so if you want to learn more about all the other things I recommend our Azure training.

Installing requirements using Azure startup tasks

Windows Azure deploys your azure web or worker role in the cloud, on a machine with Windows Server 2008 and .NET 4 pre-installed. But what if you need an additional requirement? What if you need to install some performance counter, or if you need some other piece of software like the media encoder? Then you can use a startup task to get the job done. In this blog post you will create a simple web role using ASP.NET MVC 3, then add a startup task to ensure MVC 3 is also installed on the Azure instance. For this walkthrough you’ll need Visual Studio 2010 and ASP.NET MVC 3. You’ll also need the standalone MVC 3 installer, which you can find here. Step 1: Create the Azure solution. Start by creating a new Cloud project, call it UsingStartupTasks. Click Ok. Don’t add any role just yet, so click Ok in the next screen. MVC 3 is not available from the “New Windows Azure project” dialog, so we’ll need to use another way to get an ASP.NET project in Azure… Now add a new ASP.NET MVC 3 project, calling it HelloMVC3. Select the Internet Application template, leave the rest to its defaults, then press Ok. Right-click the Roles folder beneath your cloud project and select Add->Web Role Project in Solution… Select the HelloMVC3 project in the next screen and hit Ok. Adding the Startup task Add a new folder StartupTasks to your MVC project and add the MVC installer AspNetMVC3Setup.exe to it. Open notepad.exe (don’t add the following file using Visual Studio because it will add a Byte Order Mark and the Azure runtime doesn’t like that) and create a new batch file called installmvc.cmd in the StartupTasks folder. To add it to the Visual Studio project first click on the Show All Files button in the solution explorer, and then right-click the installmvc.cmd file and select Include In Project. Do the same for the AspNetMVC3Setup.exe installer. We’ll use this batch file to execute the installer as follows: enter following in installmvc.cmd: %~dp0AspNetMVC3Setup.exe /q /log %~dp0mvc3_install.htm exit /b 0   The %~dp0 actually returns the install folder for your azure project, so the first line will run the standalone MVC3 installer, this will write any install problems to a log file called mvc3_install.htm. The %~dp0 is used to get the directory containing the startup tasks (an azure server local copy of the StartupTasks folder). The first statement will do a silent (quiet) install of MVC3, and the next line will return a success error code. Make sure both files have a build action of “none” and Copy to Output Directory set to “Copy Always”. Editing the Service definition file Finally you need to open the ServiceDefinition.csdef file and add the task to it: <?xml version="1.0" encoding="utf-8"?> <ServiceDefinition name="UsingStartupTasks" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"> <WebRole name="HelloMVC3"> <Sites> <Site name="Web"> <Bindings> <Binding name="Endpoint1" endpointName="Endpoint1" /> </Bindings> </Site> </Sites> <Endpoints> <InputEndpoint name="Endpoint1" protocol="http" port="80" /> </Endpoints> <Imports> … </Imports> <Startup> <Task commandLine="StartupTasks\installmvc.cmd" executionContext="elevated" taskType="simple" /> </Startup> </WebRole> </ServiceDefinition>   In this <Startup> element you can add any number of Task elements. Each represents a commandLine that will be executed on the installing instance prior to installing your azure project. You also get a couple of options, first you can specify the executionContext: this can be elevated or limited. Elevated gives you administrator-like privileges and is ideal for installers (which normally only work with admin privileges). Limited gives you “normal user” privileges. You can also choose the taskType. This is how the task will be executed. You get three options: simple, background or foreground. Simple means that the installer will wait for this task to complete before continuing with the next task (or the actual installation of your azure role). Background and foreground means the same thing like in threading. Background will not block the installer from continuing with the next task, and these will run in parallel. So to get MVC3 installed we need to run elevated, and we don’t want installation to continue before MVC3 has been installed, so we choose simple as the task type… Deploying to Azure Right-click on the Cloud project and select Publish… The Deploy Windows Azure project dialog opens: Select your credentials, environment and storage account. You may need to do some setup for this to work… Optionally you can configure remote desktop connections in case something went wrong, this will make it easier to see if MVC 3 was indeed installed. Click on Ok and wait… Deployment in Visual Studio should start: Wait some more till complete (because the startup tasks are executing this will take a long time): Click on the Url. You should now see the MVC 3 screen! In my next blog post I will show you how to turn this startup task into an azure startup plugin, which will make it easier to re-use this startup task.

Storing message in table storage

In my previous post I looked at getting started with table storage, in this one we will create a table for our entities and store them. As you’ll see, quite easy! So, to store an entity in table storage you start by creating a TableServiceEntity derived class (recap from previous post): public class MessageEntity : TableServiceEntity { public MessageEntity() { } public MessageEntity(string partitionKey, string rowKey, string message) : base( partitionKey, rowKey ) { Message = message; } public string Message { get; set; } }   You also need a table class, this time deriving from TableServiceContext: public class MessageContext : TableServiceContext { public const string MessageTable = "Messages"; public MessageContext(string baseAddress, StorageCredentials credentials) : base(baseAddress, credentials) { } } TableServiceContext requires a base address and credentials, and since our class derives from it we need a constructor taking the same arguments. I also have a const string for the table name. If the table doesn’t exist yet you should create it. This is easy, just add the code to create the table in the MessageContext’s static constructor: static MessageContext() { var tableClient = MyStorageAccount.Instance.CreateCloudTableClient(); tableClient.CreateTableIfNotExist(MessageTable); } A static constructor is automatically called when you use the type. Note that I use the MyStorageAccount class, which uses the same static constructor trick to initialize the storage account. public static class MyStorageAccount { public static string DataConnection = "DataConnection"; public static CloudStorageAccount Instance { get { return CloudStorageAccount.FromConfigurationSetting(DataConnection); } } static MyStorageAccount() { CloudStorageAccount.SetConfigurationSettingPublisher( (config, setter) => { setter( RoleEnvironment.IsAvailable ? RoleEnvironment.GetConfigurationSettingValue(config) : ConfigurationManager.AppSettings[config] ); RoleEnvironment.Changing += (_, changes) => { if (changes.Changes .OfType<RoleEnvironmentConfigurationSettingChange>() .Any(change => change.ConfigurationSettingName == config)) { if (!setter(RoleEnvironment.GetConfigurationSettingValue(config))) { RoleEnvironment.RequestRecycle(); } } }; }); } }   Now we are ready to add the code to create and add a message to our table. Add following code to MessageContext: public static MessageEntity CreateMessage( string message ) { return new MessageEntity(MessageTable, Guid.NewGuid().ToString(), message); } public void AddMessage(MessageEntity msg) { this.AddObject(MessageTable, msg); this.SaveChanges(); }   The CreateMessage method creates a new MessageEntity instance, with the same partition key (I don’t expect to store a lot of messages), a unique Guid as the row key, and of course the message. The AddMessage method adds this entity to the table, and then calls SaveChanges to send the new row to the table. This mechanism uses the same concepts as WCF Data Services. In the previous post we created a web site with a textbox and a button. Implement the button’s click event as follows: protected void postButton_Click(object sender, EventArgs e) { string message = messageText.Text; var msg = MessageContext.CreateMessage(message); context.AddMessage(msg); } This will allow you to add messages to storage. Before you can run this sample, you also need to setup the connection. Double-click the CloudMessages project beneath the Roles folder. This open the project’s configuration window. Select the Settings tab and add a “DataConnection” setting, select “Connection String” as the type and then select your preferred storage account. In the beginning it is best to use development storage, and that is what I did here: After running the web site you are of course wondering if your messages were actually added. So let’s add some code and UI to display the messages in the table. Start by adding the following property to MessageContext: public IQueryable<MessageEntity> Messages { get { return CreateQuery<MessageEntity>(MessageTable); } } This property returns an IQueryable<MessageEntity>, which is then used by LINQ for writing queries. To actual query is performed in our web page class. But first we need to add some UI to display the messages. Add a repeater control beneath the TextBox and Button: <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent"> <p> <asp:TextBox ID="messageText" runat="server" Width="396px"></asp:TextBox> <asp:Button ID="postButton" runat="server" OnClick="postButton_Click" Text="Post message" /> </p> <p> <asp:Repeater ID="messageList" runat="server"> <ItemTemplate> <p> <%# ((MessagesLib.MessageEntity) Container.DataItem).Message %> </p> </ItemTemplate> </asp:Repeater> </p> </asp:Content>   Now that we can display the messages, let’s add a LoadMessages method below the click event handler of the page: private void LoadMessages() { var query = from msg in context.Messages select msg; messageList.DataSource = query.ToList() .OrderBy(m => m.Timestamp) .Take(10); messageList.DataBind(); } Call this method in the Load event of the page: protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { LoadMessages(); } }   And again in the button’s click event: protected void postButton_Click(object sender, EventArgs e) { string message = messageText.Text; var msg = MessageContext.CreateMessage(message); context.AddMessage(msg); LoadMessages(); }   Run. Add some messages, and see them listed (only the first 10 messages will be displayed, change to query as you like).