mercredi 3 septembre 2014

How to solve conflicts between different version of assemblies when deploying to Windows Azure Mobile Service

It's quite a long title but it says it all. When deploying to Windows Mobile Azure Service, the hosting environment has some pre-defined assemblies version that it likes to keep.

So if you've happily updated your nuget packages and all of the sudden your Azure Mobile Service site stops and in the logs you see:

Exception=System.IO.FileLoadException: Could not load file or assembly 'System.Web.Http, Version=5.2.2.0 etc....

Or

Found conflicts between different versions of the same dependent assembly 'System.Web.Http': 5.1.0.0, 5.2.2.0. Please change your project to use version '5.1.0.0' which is the one currently supported by the hosting environment.

The kind of fun messages you'd get if you dare update those nuget packages















To solve that, we'll need to downgrade the nuget packages, which is no small feat. Obviously removing and re-adding the packages manually is out of the question; and we need a permanent solution to the package updating issue too.

Turns out NuGet 2.8 can help us with that. Here's an extract from the packages.config of the original (before the update) project.

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  
The trick is to add a version constraint like so allowedVersions="[5.1.2]". It's all described on NuGet's documentation. Applying those constraints links to something like this:

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    
Then it's just a matter of running Update-Package -reinstall to restore the packages to their right version... well not quite, for me it re-installed all the other packages in the projects in the solution, took a long time and spat a completely bogus solution that did not compile. The (much) longer approach is to update them one by doing something like:

Get-Project -All | ?{ $_ | Get-Package | ?{ $_.Id -eq 'Microsoft.AspNet.WebApi.Core' } } | %{ $_ | Update-Package Microsoft.AspNet.WebApi.Core -Reinstall }


Which is very tedious. Till next time, happy coding.

vendredi 24 janvier 2014

Windows Store C# Application: Reading a network stream

Here's a little snippet that will allow a Windows Store C# application send a command string to a server and then get a reply:

private async Task<string> DoCommand(string command)
{
    StringBuilder strBuilder = new StringBuilder();
    using (StreamSocket clientSocket = new StreamSocket())
    {
        await clientSocket.ConnectAsync(_serverHost, _serverPort);
        using (DataWriter writer = new DataWriter(clientSocket.OutputStream))
        {
            writer.WriteString(command);
            await writer.StoreAsync();
            writer.DetachStream();
        }
        using (DataReader reader = new DataReader(clientSocket.InputStream))
        {
            reader.InputStreamOptions = InputStreamOptions.Partial;
            await reader.LoadAsync(8192);
            while (reader.UnconsumedBufferLength > 0)
            {
                strBuilder.Append(reader.ReadString(reader.UnconsumedBufferLength));
                await reader.LoadAsync(8192);
            }
            reader.DetachStream();
        }
    }
    return (strBuilder.ToString());
}

What's important is the loop that will get the data until the end of the stream. This example is for a server that will reply some data and then close the connection; it's not suitable for an endless stream of data. I use this particular example to connect to CGMiner's api, where I send it a command string and it replies with some data, then close the connection.

mardi 14 janvier 2014

Windows Store & WCF Frustration

I was doing a nice & simple news app for the Windows Store in C# that uses WCF as its backend, and everything was going fine (by the book).

I created the Windows Store project, added Service Reference and started to code away happily. But at some point I decided to indicate in my WCF contract that my service can throw FaultExceptions.

It was already throwing FaultExceptions in some methods as part of its "normal" operation, and it was working fine (the Windows Store app was getting the FaultExceptions with all the metadata I attached) but I wanted to make it explicit for the other developers who were using my service to see which method threw FaultExceptions and which did not.

That was a very bad mistake that took an entire evening with the team to figure out: do not use FaultContract in your WCF service if your client is a Windows Store app. It will simply fail to generate the client proxy the next time you do an update service reference. That is the worst kind of error, because there could be some time between the moment you've added the FaultContract and the moment you  wonder where on Earth is your proxy client. And it does not even put out a message, warning or error when you update the service reference: it includes all the classes except the client proxy. A silent but deadly error.
And that lead us to a bug hunt where we re-created the Web.configs, created test projects trying to reproduce the bug, reverted files etc...