Friday, 27 January 2012

Windows Azure and type initializer for 'System.ServiceModel.Diagnostics.TraceUtility' threw an Exception

I've been working on a new product that I'm with Windows Azure and today whilst I came to debug a WCF service within it stumbled apon an error that at first glance doesn't make a whole lot of sence, but with a bit of working backwards turns out is quite simple to fix.

The scenario: I have a WCF service setup to run in a WorkerRole as part of an Azure solution, pretty simple.

To enable me to see what was going on clearer with my service i decided to configure my system.diagnostic listeners and added the default AzureLocalStorage listener, which is created automatically for you, to my service model and message logging.
<system.diagnostics>    
    <sharedListeners>
      <add name="AzureLocalStorage" type="ServiceAuthenticationGatewayWorkerRole.AzureLocalStorageTraceListener, ServiceAuthenticationGatewayWorkerRole"/>
    </sharedListeners>
    <sources>
      <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing">
        <listeners>
          <add name="AzureLocalStorage"/>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
        <listeners>
          <add name="AzureLocalStorage"/>
        </listeners>
      </source>
    </sources>
   </system.diagnostics>
However upon running the application nothing would happen for around 30 - 60 seconds and then I was greeted with a nice TypeInitializationException.

Viewing the detail of this and the inner exceptions eventually led me to the following message:
{"Could not create xxxxxWorkerRole.AzureLocalStorageTraceListener, xxxxxxxx."}

So the AzureLocalStorageTraceListener was blowing up on type initialisation, popping open the code you see that the constructor does some work, specifically it gets the log directory of the WCF log file and combines the filename and path etc.

This looked normal, I put a breakpoint in and stepped through the GetLogDirectory method to find which line threw, my guess would be its where it calls into the RoleEnvironment and gets the local resource. Turns out this is exactly where it threw.

I had a quick gander at MSDN and found that you pass the local resource name to the method you want to load. This led me to think that the resource wasn't defined so next up was the storage configuration.

With Azure you configure local storage per role, to change the settings right click the worker role within the main Azure project, it will be in a folder called roles and open properties. You will then get a screen similar to what I had.
You will note, as I did, considering I thought I had local storage and was accessing it via the key, it wasn't setup within the role properties :(

Simply using the Add Local Storage button and entering the correct details let the project startup and start logging correctly.

What I found here is another case where the framework gives you the generic error message and not the exception that was really being thrown, RoleEnvironmentException which would have made me look at the local storage settings a lot quicker.

Any way there it is, I hope this helps :)

Tuesday, 24 January 2012

Tidying up user data for display

Today I was tidying up a quick WPF application i had built for a client. It simply renders "today's schedule" in a way that is meaningful for them and allows them to view it on multiple screens and print as necessary.

Development was quick as it only consumed several Google Calendar feeds and based upon my test data worked well.

However today seeing used in real life made me rethink how i rendered the data, in my test data I entered items how I would enter them, this is important, I entered them using sentence casing for paragraphs, title casing for titles etc. However due to the way some of the users worked everything was being entered in CAPS :(

Functionally the app works fine, however for me, and I'm no designer, it looked odd. So I opened the solution again and started to look at ways of improving this. My initial thoughts were to apply some sort of styling, think text-transform:capitalize; if you were using CSS, but alas XAML doesn't have this. I then thought I could implement a custom formatter that I could use in the XAML upon databinding, I could have done this, but I chose not too. Although it makes sense to do so, I started thinking about how I will probably end up using the data access / domain code in this project later on in another GUI where I will no doubt have the same problem.

As a result I wanted to "fix" this data at the domain level in C#. As soon as you hit the code you know there are many ways of achieving this, you could go down the route of RegEx replacing, iterating through the string looking for .'s or whitespace if you want title case etc and then do some replacing. You could even just specify everything is lowercase, but for me none of these fully fitted what I wanted / effort level I wanted to put in for an issue that only I really had.

What I really wanted was a ToTitleCase or ToSentanceCase that already exists the framework, I didn't want to go grab extension methods which I'm almost certain there will be many of. A quick bit of poking around led me to this gem.
TextInfo.ToTitleCase
I refer to MSDN the ToTitleCase method "Converts the specified string to titlecase." Great, exactly what I wanted. It's easy to use too:



// Defines the string with mixed casing.
      string myString = "wAr aNd pEaCe";

      // Creates a TextInfo based on the British culture.
      TextInfo myTI = new CultureInfo("en-GB",false).TextInfo;

      // Changes a string to titlecase.
      Console.WriteLine( "\"{0}\" to titlecase: {1}", myString, myTI.ToTitleCase( myString ) );

Fantastic, build, run, enjoy.....
Well kinda.... This is one method you really do need to read the remarks for on the MSDN page,
this method does not currently provide proper casing to convert a word that is entirely uppercase, such as an acronym.
and
the ToTitleCase method provides an arbitrary casing behavior which is not necessarily linguistically correct. A linguistically correct solution would require additional rules, and the current algorithm is somewhat simpler and faster. We reserve the right to make this API slower in the future.

This actually meant that in my case, when people added descriptions entirely in uppercase the method did nothing. Bit of a shame, I made the conscious decision that Titles I would use ToTitleCase in the hope to improve titles where people enter one with all lower case or mix use, but if they use entirely uppercase then I am unfortunate. However for descriptions I decided to lowercase the string and then use ToTitleCase. Now this isn't sentence casing but it does look better than all caps. This is a compromise, I was able to improve the app without spending too much time on it.

ToTitleCase is one of those hidden gems, (just like using XmlConvert.ToString with a DateTime will give you the DateTime in RFC 3339 which is fantastic for use with Google Calendar API's etc... but that's a blog post for another day ... ), which can save you time and provide quick wins, it's also culture sensitive which can really help you out if you have a globalised project, just be clear on what it does and what it doesn't do.

Enjoy

Monday, 16 January 2012

Tricky times using the MVC3 Date Validator and JQuery UI DatePicker

Today I came across a strange problem whilst seemingly writing a simple MVC3 prototype. My prototype had a textbox for a date value which I then used jQuery UI to append a date picker too. I was also using unobtrusive validation and data annotations on my models to seemingly "speed up" developing my prototype.

Although I thought I had wrote everything correctly whenever I tried to submit my form in Chrome I was getting a random error: Please enter a valid date. Originally I had suspected I had messed up the date time formatting, as I was using en-GB format, not the default en-US. Much time wasted and many things I tried had no effect.

I then by chance loaded the page in Internet Explorer only to find the issue had "vanished", so I went back to Chrome and nope it was back. Upon double checking my code I pondered if using the classname of "date" on my element could cause problems and a bit of Googling confirmed this. In short don't apply a date picker to an element with a class name of "date" otherwise Chrome gets all confused. I believe this is due to the page being HTML5 and the way Chrome parses elements etc, but for now I don't need to know too much about that ;)

Hurrah everything works again and only x amount of time wasted :(