Tuesday, 30 October 2012

Windows Azure Storage URLs

Following on from the previous post about accessing the Azure Storage Emulator, you would also need to know what the actual endpoint URLs are.


The following URL formats are used for addressing resources running on Azure and on the storage emulator:

Blob Service

Emulator - http://127.0.0.1:10000/storageaccount/
Azure - http://storageaccount.blob.core.windows.net/

Queue Service

Emulator - http://127.0.0.1:10001/storageaccount/
Azure - http://storageaccount.queue.core.windows.net/

Table Service

Emulator - http://127.0.0.1:10002/storageaccount/
Azure - http://storageaccount.table.core.windows.net/

For your emulator, the "storageaccount" is always "devstoreaccount1".

The "storageaccount" value for Azure is whatever you created. The name is always lowercase and cannot contain spaces or special characters.

Monday, 29 October 2012

Access to the Windows Azure Storage Emulator

Should you wish to do any work against the Windows Azure Storage Emulator, say testing the REST API, you might be wondering what the account name and account key might be.

Those details for the Storage Emulator are the same for every single installation of the developer tools, they do not vary between machines.

They are published here: http://msdn.microsoft.com/en-us/library/windowsazure/gg432983.aspx

Account name:

devstoreaccount1

Account key:

Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==

Giving you a connection string of:

DefaultEndpointsProtocol=https;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==

Though the following is also a valid connection string for the Storage Emulator:

usedevelopmentstorage=true

The individual account name and key would be of use when you don't have a connection string, like the aforementioned REST API.

Friday, 26 October 2012

A "processing" dialogue box with jQuery

Suppose you want to create something like the following:



Common scenarios are when a user submits something and you want to wait for a response without refreshing the page.

This is easy!

First add two NuGet packages to your web application:

    install-package jQuery-UI
    install-package jQuery.UI.Combined

Then use the following mark-up:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="Content/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
    <link href="Content/themes/base/jquery.ui.core.css" rel="stylesheet" type="text/css" />
    <link href="Content/themes/base/jquery.ui.theme.css" rel="stylesheet" type="text/css" />
    <link href="Content/themes/base/jquery.ui.dialog.css" rel="stylesheet" type="text/css" />
    <script src="Scripts/jquery-1.8.2.js" type="text/javascript"></script>
    <script src="Scripts/jquery-ui-1.9.0.js" type="text/javascript"></script>
</head>
    <body>
        <script type="text/javascript">
            $(document).ready(function () {
                $("#progressDialog").dialog({
                    autoOpen: false,
                    draggable: false,
                    modal: true,
                    resizable: false,
                    closeOnEscape: false,
                    open: progressDialogOpen
                });
            });
 
            function progressDialogOpen() {
                $(".ui-dialog-titlebar-close"this.parentNode).hide();
            }
 
            function progressDialogClose() {
                $("#progressDialog").dialog('close');
            }
 
            function doSomethingOpen() {
                $("#progressDialog").dialog('open');
                setTimeout(progressDialogClose, 3000);
                return false;
            }
 
            function doSomethingClose() {
                progressDialogClose();
            }
        </script>
        <button onclick="doSomethingOpen()">Open</button>
        <button onclick="doSomethingClose()">Close</button>
        <div id="progressDialog" title="Processing">
            <img alt="Processing..." src="Content/images/YourAnimatedProcessingImage.gif" />
        </div>
    </body>
</html>


Note that this example just puts in a time out to simulate something happening. You can replace the call to "setTimeout" with some server call.

And that is it.

Thursday, 25 October 2012

Building Windows Services with TopShelf

TopShelf is a framework you can use to build windows services which can be installed easily. It is used by such famous products as NServiceBus. It allows you to create windows services that you don't have to install with "installutil.exe". The windows service you create is self installing.

When using TopShelf, you install your windows service by running the following command:

    Acme.TopShelfExample.Windows.Service.exe install

Which would result in the following console output:


    Configuration Result:
    [Success] Name ExampleWorker
    [Success] DisplayName Example Worker
    [Success] Description An Example Worker.
    [Success] ServiceName ExampleWorker
    Topshelf v3.0.105.0, .NET Framework v4.0.30319.269

    Running a transacted installation.

    Beginning the Install phase of the installation.
    Installing Example Worker service
    Installing service ExampleWorker...
    Service ExampleWorker has been successfully installed.
    Creating EventLog source ExampleWorker in log Application...

    The Install phase completed successfully, and the Commit phase is beginning.

    The Commit phase completed successfully.

    The transacted install has completed.


Which is pretty much the same as you get using "installutil.exe".

To uninstall, run the following:

    Acme.TopShelfExample.Windows.Service.exe uninstall

Which would result in the following console output:


    Configuration Result:
    [Success] Name ExampleWorker
    [Success] DisplayName Example Worker
    [Success] Description An Example Worker.
    [Success] ServiceName ExampleWorker
    Topshelf v3.0.105.0, .NET Framework v4.0.30319.269


    The uninstall is beginning.
    Uninstalling ExampleWorker service
    Removing EventLog source ExampleWorker.
    Service ExampleWorker is being removed from the system...
    Service ExampleWorker was successfully removed from the system.

    The uninstall has completed.


Again, the same as you'd get using "installutil.exe".

To use TopShelf for your windows service, create a console application and install TopShelf using NuGet:

    install-package TopShelf

The following code should get you started:


namespace Acme.TopShelfExample.Windows.Service
{
    using Topshelf;
 
    internal class Program
    {
        internal static void Main(string[] args)
        {
            HostFactory.Run(hostConfigurator =>
            {
                hostConfigurator.Service<ExampleWorker>(serviceConfigurator =>
                {
                    serviceConfigurator.ConstructUsing(name => new ExampleWorker());
                    serviceConfigurator.WhenStarted(ew => ew.Start());
                    serviceConfigurator.WhenStopped(ew =>
                        {
                            ew.Stop();
 
                            // And dispose or release any component containers (e.g. Castle) 
                            // or items resolved from the container.
                        });
                });
                hostConfigurator.RunAsLocalSystem();
                hostConfigurator.SetDescription("An Example Worker.");
                hostConfigurator.SetDisplayName("Example Worker");
                hostConfigurator.SetServiceName("ExampleWorker"); // No spaces allowed
                hostConfigurator.StartAutomatically();
            });
        }
    }
}



namespace Acme.TopShelfExample.Windows.Service
{
    using System;
    using System.Globalization;
    using System.Threading;
 
    public abstract class Worker
    {
        private Thread thread;
 
        private bool stop = true;
 
        protected Worker()
        {
            this.SleepPeriod = new TimeSpan(0, 0, 0, 10);
            this.Id = Guid.NewGuid();
        }
 
        public TimeSpan SleepPeriod { getset; }
 
        public bool IsStopped { getprivate set; }
 
        protected Guid Id { getprivate set; }
 
        public void Start()
        {
            string logMessage = string.Format(CultureInfo.CurrentCulture, "Starting worker of type '{0}'."this.GetType().FullName);
            System.Diagnostics.Debug.WriteLine(logMessage);
            this.stop = false;
 
            // Multiple thread instances cannot be created
            if (this.thread == null || this.thread.ThreadState == ThreadState.Stopped)
            {
                this.thread = new Thread(this.Run);
            }
 
            // Start thread if it's not running yet
            if (this.thread.ThreadState != ThreadState.Running)
            {
                this.thread.Start();
            }
        }
 
        public void Stop()
        {
            string logMessage = string.Format(CultureInfo.CurrentCulture, "Stopping worker of type '{0}'."this.GetType().FullName);
            System.Diagnostics.Debug.WriteLine(logMessage);
            this.stop = true;
        }
 
        protected abstract void DoWork();
 
        private void Run()
        {
            try
            {
                try
                {
                    while (!this.stop)
                    {
                        this.IsStopped = false;
                        this.DoWork();
                        Thread.Sleep(this.SleepPeriod);
                    }
                }
                catch (ThreadAbortException)
                {
                    Thread.ResetAbort();
                }
                finally
                {
                    this.thread = null;
                    this.IsStopped = true;
                    string logMessage = string.Format(CultureInfo.CurrentCulture, "Stopped worker of type '{0}'."this.GetType().FullName);
                    System.Diagnostics.Debug.WriteLine(logMessage);
                }
            }
            catch (Exception e)
            {
                string exceptionMessage = string.Format(CultureInfo.CurrentCulture, "Error running the '{0}' worker."this.GetType().FullName);
                System.Diagnostics.Debug.WriteLine(exceptionMessage, e);
                throw;
            }
        }
    }
}



namespace Acme.TopShelfExample.Windows.Service
{
    using System.Diagnostics;
 
    public class ExampleWorker : Worker
    {
        protected override void DoWork()
        {
            Debug.WriteLine("Example Worker is doing something.");
        }
    }
}


And that is it.

Wednesday, 24 October 2012

Service Bus for Windows Server

Microsoft have released Service Bus for Windows Server.

http://msdn.microsoft.com/en-us/library/windowsazure/jj193022(v=azure.10).aspx

This is essentially an on premise equivalent of the Windows Azure Service Bus (not to be confused with Azure Storage Queues). The rumour is that development for MSMQ has stopped and Service Bus is the strategic replacement.

One other point of note is that this solves one annoying issue when developing with Windows Azure. Pretty much all of the main components to Windows Azure have local "equivalents"...

  • Local development with Cloud Services is supported by the Compute Emulator.
  • Local development with Azure Storage (Blobs, Tables, Queues) is supported by the Storage Emulator.
  • Local development with SQL Azure can be achieved (with care over which features you use) on SQL Server.
...but the Azure Service Bus has never had an answer for local development. Now it does, the Service Bus for Windows Server behaves the same.

Update: Blog post from Microsoft.

Tuesday, 23 October 2012

MSBuild code formatting

Speaks for itself...

Bad

  <Target Name="MyExampleTarget1">
      <SomeMSBuildTaskThatDoesSomethingOrOtherWithALongName SomePropertyForTheTaskWithALongName="value1" AnotherPropertyForTheTaskWithALongName="value2" />
      <MSBuildTaskWithShortNameName AProperty="value3" />
  </Target>

The end of the line extends outside the editor window so you can't see the end argument without scolling horizontally.

Bad

  <Target Name="MyExampleTarget2">
      <SomeMSBuildTaskThatDoesSomethingOrOtherWithALongName SomePropertyForTheTaskWithALongName="value1" 
                                                            AnotherPropertyForTheTaskWithALongName="value2" />
      <MSBuildTaskWithShortName SomeProperty="value3" />
  </Target>
 
The properties don't line up ("SomeProperty" not aligned with the properties from the previous task) making it a bit harder to read.

Good

  <Target Name="MyExampleTarget3">
      <SomeMSBuildTaskThatDoesSomethingOrOtherWithALongName 
          SomePropertyForTheTaskWithALongName="value1"
          AnotherPropertyForTheTaskWithALongName="value2" />
      <MSBuildTaskWithShortName 
          SomeProperty="value3" />
  </Target>
 
Everything almost always fits in the editor window (no need to scroll horizontally) and everything lines up making it easy on the eye.

Monday, 22 October 2012

32GB Surface with Windows RT sold out in the UK

All 32GB Surface models have sold out ahead of the launch in the UK!




About Me