Fixing MSDeploy Error: Web deployment task failed. (Root element is missing.)

In one of my MRCollective open source projects AzureWebFarm, we configure a set of Windows Azure Web Roles such that a change deployed to any of them using MSDeploy will automatically sync to the other servers. Up to and including MSDeploy v2 this worked fine, but in a Windows Server 2012 Azure server environment MSDeploy v3 returns the following exception (if deploying to a role with more than one instance):

Web deployment task failed. (Root element is missing.)

The more verbose version of this exception:

System.Xml.XmlException: Root element is missing.
     at System.Xml.XmlTextReaderImpl.ThrowWithoutLineInfo(String res)
     at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
     at System.Xml.XmlReader.MoveToContent()
     at Microsoft.Web.Deployment.TraceEventSerializer.Deserialize(Stream responseStream, DeploymentBaseContext baseContext, DeploymentSyncContext syncContext)
     at Microsoft.Web.Deployment.AgentClientProvider.RemoteDestSync(DeploymentObject sourceObject, DeploymentSyncContext syncContext, Nullable`1 syncPass) at Microsoft.Web.Deployment.DeploymentObject.SyncToInternal(DeploymentObjectdestObject, DeploymentSyncOptions syncOptions, PayloadTable payloadTable, ContentRootTable contentRootTable, Nullable`1 syncPassId) at Microsoft.Web.Deployment.DeploymentObject.SyncTo(DeploymentProviderOptions providerOptions, DeploymentBaseOptions baseOptions, DeploymentSyncOptions syncOptions) at MSDeploy.MSDeploy.ExecuteWorker()

You might also observe the following exception on the server:

wmsvc.exe Error: 0 : ERROR_SERIALIZER_ALREADY_DISPOSED - The object 'Microsoft.Web.Deployment.TraceEventStreamSerializer' has already been disposed. 
ProcessId=3404
ThreadId=12
DateTime=2013-03-31T10:00:40.4910669Z
Timestamp=8992845619

Tracing this further showed that MSDeploy v3 appears to use multiple connections, and those connections were distributed to multiple servers in our test web farms for a single deployment, causing msdeploy to fail pretty miserably with these XML errors.

The solution was to ensure that all MSDeploy connections from the client end up at a single server in the web farm, rather than being distributed to multiple servers. To achieve this in Windows Azure, you can create a custom load balancer endpoint in ServiceDefinition.csdef - take a look at the loadBalancerProbe="WebDeploy" and the LoadBalancerProbe config setting in our example ServiceDefinition.csdef for reference. You can read more about custom load balancer endpoints in this post.

That custom probe hits a file we created called Probe.aspx. That file contains a really simple piece of code which attempts to get an Azure Blob Storage lease on a blob we specify. Only one instance will ever be able to get that lease at a time, and if it ever fails, another instance will pick it up, ensuring this solution still gives us redundancy for deployments.

Should an instance successfully get the lease, it will return a HTTP OK status on that load balancer endpoint, and the Azure Fabric will know that it's fine to route web deploy requests to that instance. All the other instances will fail to get the lease, and return a HTTP error status back to the endpoint, meaning the Azure Fabric will not send any web deploy requests to all other instances (ensuring it all works happily with MSDeploy v3).

Windows Azure Websites PHP: Cache Service via Memcache

I've been migrating a PHP application to Azure Websites which uses memcached extensively. You can connect to Azure Cache Service (still in the preview program) using the memcache protocol, effectively making the migration seamless from an application point of view. I couldn't find much out there on how to enable this PHP extension in Azure Websites, so I thought I'd write up the steps I followed. First, open up the configure tab of your Azure Website. Take special note below of your PHP version and platform - you'll need both to determine which version of the memcache extension

Check version and bitness

Based on the above, download the extension DLL from here - make sure you grab the NTS (non thread safe) version: http://pecl.php.net/package/memcache/3.0.8/windows You might also want to check this page to make sure you're grabbing the latest version available http://pecl.php.net/package/memcache Your downloaded file should look something like this: php_memcache-3.0.8-PHP_VERSION-nts-vc9-PLATFORM.zip. Extract and upload the DLL to your site root using your chosen deployment method for the site (source control, dropbox, FTP etc). A fairly common recommendation is to place these PHP extensions in a folder called "bin", which automatically protects them from being downloaded by the outside world over HTTP. Scroll down on the configure tab until you see app settings. Here, we configure PHP to look for your extension DLL by adding a variable called PHP_EXTENSIONS and pointing it to your uploaded DLL:

app settings php extensions

Save, and you should be good to go! You can verify this by creating a PHP file in your site with the following... <?php phpinfo(); ?> ...and then viewing that page in your browser:

memcache result

A quick last tip - you can easily add multiple PHP extensions this way. In your PHP_EXTENSIONS app settings variable, just separate the DLL names by commas. I'll be following this post up with a way to do this for all your sites without needing to upload the DLL into each one individually. Have fun and good luck!

Unit testing MVC3/MVC4 Model Binders

Update: I'm always trying to find improved ways of implementing and testing model binders. See https://github.com/MattDavies/MvcModelBinderTesting for the latest version, and feel free to send a pull request if you have any suggestions!

Here's a really simple helper base class for testing MVC model binders. There's an example at the bottom of this post covering usage of this class.

This will work for simple model binders which don't take IoC dependencies, use the BindingContext to retrieve values and don't use the ControllerContext parameter passed to BindModel():

public abstract class ModelBinderTestBase<TBinder, TModel> where TBinder : IModelBinder, new()
{
    private ModelBindingContext _bindingContext;
    private NameValueCollection _formCollection = new NameValueCollection();

    protected void SetFormValues(NameValueCollection formValues)
    {
        _formCollection = formValues;
    }

    protected TModel BindModel()
    {
        SetupBindingContext();
        new TBinder().BindModel(null, _bindingContext);
        return (TModel)_bindingContext.ModelMetadata.Model;
    }

    private void SetupBindingContext()
    {
        var valueProvider = new NameValueCollectionValueProvider(_formCollection, null);
        var modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TBinder));
        _bindingContext = new ModelBindingContext
        {
            ModelName = typeof(TModel).Name,
            ValueProvider = valueProvider,
            ModelMetadata = modelMetadata
        };
    }
}

We can extend this base class to cover dependencies by resolving the model binder using your favourite mocking library. I use a library I helped create called AutofacContrib.NSubstitute:

public abstract class ModelBinderTestBase<TBinder, TModel> where TBinder : IModelBinder
{
    private ModelBindingContext _bindingContext;
    private NameValueCollection _formCollection = new NameValueCollection();

    protected void SetFormValues(NameValueCollection formValues)
    {
        _formCollection = formValues;
    }

    protected TModel BindModel()
    {
        SetupBindingContext();
        new AutoSubstitute().Resolve<TBinder>().BindModel(null, _bindingContext);
        return (TModel)_bindingContext.ModelMetadata.Model;
    }

    private void SetupBindingContext()
    {
        var valueProvider = new NameValueCollectionValueProvider(_formCollection, null);
        var modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TBinder));
        _bindingContext = new ModelBindingContext
        {
            ModelName = typeof(TModel).Name,
            ValueProvider = valueProvider,
            ModelMetadata = modelMetadata
        };
    }
}

We can easily extend the class to support ControllerContext using the same mocking library.

Final version (Autofac / NSubstitute / NUnit) - feel free to adjust to suit your needs or leave a comment if you need a hand:

public abstract class ModelBinderTestBase<TBinder, TModel> where TBinder : DefaultModelBinder
{
    #region Setup base + private methods

    private ControllerContext _context;
    private ModelBindingContext _bindingContext;
    protected AutoSubstitute AutoSubstitute;
    private NameValueCollection _formCollection;

    [SetUp]
    protected void Setup()
    {
        AutoSubstitute = new AutoSubstitute();
        var httpContext = Substitute.For<HttpContextBase>();
        var request = Substitute.For<HttpRequestBase>();
        httpContext.Request.Returns(request);
        var controllerContext = Substitute.For<ControllerContext>();
        controllerContext.HttpContext = httpContext;
        AutoSubstitute.Provide(request);
        AutoSubstitute.Provide(httpContext);
        AutoSubstitute.Provide(controllerContext);

        _context = AutoSubstitute.Resolve<ControllerContext>();
    }

    private void SetupBindingContext()
    {
        _formCollection = _context.HttpContext.Request.Form;
        var valueProvider = new NameValueCollectionValueProvider(_formCollection, null);
        var modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TBinder));
        _bindingContext = new ModelBindingContext
        {
            ModelName = typeof(TModel).Name,
            ValueProvider = valueProvider,
            ModelMetadata = modelMetadata
        };
    }

    #endregion

    [Test]
    public void Bind_to_correct_model()
    {
        var attr = (ModelBinderTypeAttribute)Attribute.GetCustomAttribute(typeof(TBinder), typeof(ModelBinderTypeAttribute));
        Assert.That(attr, Is.Not.Null, "The ModelBinderType attribute is missing");
        Assert.That(attr.TargetTypes, Is.Not.Null, "No bindings are defined");
        Assert.That(attr.TargetTypes.ToList()[0], Is.EqualTo(typeof(TModel)), String.Format("The binding is incorrect; it should be {0}", typeof(TModel).FullName));
    }

    protected void SetFormValues(NameValueCollection formValues)
    {
        _context.HttpContext.Request.Form.Returns(formValues);
    }

    protected TModel BindModel()
    {
        SetupBindingContext();
        AutoSubstitute.Resolve<TBinder>().BindModel(_context, _bindingContext);
        return (TModel)_bindingContext.ModelMetadata.Model;
    }

    protected void AssertModelError(string key, string error)
    {
        Assert.That(_bindingContext.ModelState.ContainsKey(key), key + " not present in model state");
        Assert.That(_bindingContext.ModelState[key].Errors.Count, Is.EqualTo(1), "Expecting an error against " + key);
        Assert.That(_bindingContext.ModelState[key].Errors[0].ErrorMessage, Is.EqualTo(error), "Expecting different error message for model state against " + key);
    }
}

Example model:

public class ExampleViewModel
{
    public int? TestInteger { get; set; } 
}

Example model binder:

[ModelBinderType(typeof(ExampleViewModel))]
public class ExampleModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var viewModel = new ExampleViewModel();

        var monkey = bindingContext.ValueProvider.GetValue("someNumber");
        if (monkey == null)
        {
            bindingContext.ModelState.AddModelError("TestInteger", "You didn't submit a number.");
        }
        else
        {
            viewModel.TestInteger = (int?) monkey.ConvertTo(typeof (int?));
        }

        bindingContext.ModelMetadata.Model = viewModel;
        return base.BindModel(controllerContext, bindingContext);
    }
}

Example test:

[TestFixture]
public class ExampleModelBinderShould : ModelBinderTestBase<ExampleModelBinder, ExampleViewModel>
{
     [Test]
     public void Have_int_set_to_input()
     {
         SetFormValues(new NameValueCollectionsomeNumber);

         var vm = BindModel();

         Assert.That(vm.TestInteger, Is.EqualTo(3));
     }

    [Test]
    public void Not_bind_if_no_integer_submitted()
    {
        var vm = BindModel();

        Assert.That(vm.TestInteger, Is.Null);
        AssertModelError("TestInteger", "You didn't submit a number.");
    }
}

Azure Websites: Converting .htaccess rewrite rules to the IIS web.config format

Increasingly when using Azure Websites, I'm finding the need to convert .htaccess files provided with PHP websites into web.config files that Azure/IIS understand.

A quick helpful tip, IIS can do this for you (after installing the URL Rewrite extension):

1) Open the IIS Management Console on your local machine. Step 1

2) Open the URL Rewrite section under Default Web Site (or any other Site). Step 2

3) Click on Import Rules... on the right menu. Step 3

4) Paste the contents of your .htaccess file into the Rewrite Rules field. Step 4

5) Create a new web.config file using the following template, filling in the rules with the XML from the XML View.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <!-- Paste rules from XML View here -->
  </system.webServer>
</configuration>

6) Upload this web.config file to the root folder of your Azure Websites PHP site.

You may see warnings when doing the conversion - it's worth checking these manually before using the generated web.config rules. A common example is that RewriteBase is unsupported - IIS treats this a little differently and infers the base URL from the location of the web.config.

Safely wake and exit a sleeping C# thread without Thread.Abort()

As covered in numerous other posts, Thread.Abort() is a dangerous approach to exiting a thread and can have many unintended consequences that are difficult to track down.

In Azure Web Farm, I ran into a situation where on a role stopping, I needed to safely terminate multiple running threads (some of which had regular Thread.Sleep() calls in between processing loops).

You can solve this problem using the amazing Task Parallel Library in combination with Cancellation Tokens and Wait Handles. There are definitely many other ways to do this - I'll first demo two solutions that aren't as safe and explain why.

Option 1 - Thread.Abort()

The following is an example of solving this problem with Thread.Abort() - simple, but can cause unintended side effects in other areas of your application:

private readonly Thread _thread;

public void Start()
{
    _thread = new Thread(() =>
    {
        while (true)
        {
            // Perform check or processing

            Thread.Sleep(TimeSpan.FromSeconds(10));
        }
    });
}

public void Stop()
{
    _thread.Abort();
}

Option 2 - TPL with Monitor Sync

To improve upon aborting the thread directly, we can wake up the thread in the middle of Thread.Sleep() and safely end it using TPL and Locks:

private CancellationTokenSource _cancellationTokenSource;
private readonly object _lockObject = new object();

public void Start()
{
    // Create a new Cancellation Token Source - this contains a shared object used to pass a cancel message to TPL
    _cancellationTokenSource = new CancellationTokenSource();
    Task.Factory.StartNew(() =>
    {
        while (true)
        {
            // Perform check or processing

            lock (_lockObject)
            {
                // Same as a Thread.Sleep(), but it will wake up if signalled by Monitor.Pulse()
                Monitor.Wait(_lockObject, TimeSpan.FromSeconds(10));
                // After 10 seconds have passed or we have been signalled, check the Cancellation Token
                if (_cancellationTokenSource.Token.IsCancellationRequested)
                    return;
            }
        }
    }, _cancellationTokenSource.Token);
}

public void Stop()
{
    // Set the Cancellation Token status to Cancelled
    _cancellationTokenSource.Cancel();
    // Wake up the running thread if it is currently sleeping in a Monitor.Wait()
    lock (_lockObject)
    {
        Monitor.Pulse(_lockObject);
    }
}

Option 3 - TPL with Reset Events (Safest solution I can find)

The above solution is a definite improvement, but Monitor pulses can be lost between threads in certain race conditions (see This excellent StackOverflow post for more detail). A safer alternative is therefore to use reset events, at the potential cost of slightly lower performance than locking. See the final solution below:

private CancellationTokenSource _cancellationTokenSource;
private ManualResetEvent _resetEvent;

public void Start()
{
    _cancellationTokenSource = new CancellationTokenSource();
    // Set up a signal object in a default false state, to be used for waking up the Start() thread if sleeping
    _resetEvent = new ManualResetEvent(false);

    Task.Factory.StartNew(() =>
    {
        while (true)
        {
            // Perform check or processing

            _resetEvent.WaitOne(TimeSpan.FromSeconds(10));
            if (_cancellationTokenSource.Token.IsCancellationRequested)
                return;
        }
    }, _cancellationTokenSource.Token);
}

public void Stop()
{
    // First set the cancellation token to Cancelled
    _cancellationTokenSource.Cancel();
    // Now wake up the Start() thread if it is currently sleeping
    _resetEvent.Set();
}