Thursday 23 December 2010

switch vs Select Case

I knew if I looked long enough, I'd find something you can do in VB.NET that you can't do in C#. And I think I just found it.


Consider this bit of markup:
Why is it not possible to use an existing approved supplier?
<asp:radiobutton id="ClientNominatedRadioButton" runat="server" text="Nominated/named by client" GroupName="NewSupplierReasonRadioButtonGroup" />
<asp:radiobutton id="AlreadyOnSiteRadioButton" runat="server" text="Already on site" GroupName="NewSupplierReasonRadioButtonGroup" />
<asp:radiobutton id="NewLocationRadioButton" text="New location and no existing supplier" runat="server" GroupName="NewSupplierReasonRadioButtonGroup" />
<asp:radiobutton id="OtherRadiobutton" runat="server" text="Other (please state)" GroupName="NewSupplierReasonRadioButtonGroup" runat="server" />

At some point, I'll want to examine this set of radio buttons to deduce which one is selected. In VB.NET, I would normally do this with a Select Case construct, viz.
Select Case True

    Case ClientNominatedRadioButton.Checked

    Case AlreadyOnSiteRadioButton.Checked

    Case NewLocationRadioButton.Checked

    Case OtherRadiobutton.Checked

End Select
which I always think is a more elegant construct than a thousand 'if...then...else if...then..else if' blocks.

But it seems this construct is not available in C# - here's a screenshot from Visual Studio:


 
 
 
 
 
 
 
 
 
The tooltip for the red squiggly reads 'Code is unreachable. A constant value is expected'.
 
All of which leaves me slightly confused. If they compile down to the same bytecode then why does this approach work in only one language? And is there a more elegant way to determine the selected radiobutton than the aforementioned 'if...then' block?

Wednesday 25 August 2010

DateTime.DaysInMonth

I stumbled upon this yesterday and thought it was worth publicising a bit.


I'm writing a tidgy little app that will take a load of data about our press releases out of one of our databases and turn into flat HTML files. It needs to write separate files for years and months - years are easy as it's just a for loop, and months are also a for loop, but I need to know the end date for each month so I can create the appropriate SQL query. I'd written a switch block to calculate the last day of the month:


for (int i = 1; i < 13; i++)
{
    DateTime startDate = new DateTime(int.Parse(year), i, 1, 0, 0, 0);
    DateTime endDate;


    switch (i)
    {
        case 9, 4, 6, 11:
            endDate = new DateTime(int.Parse(year), i, 30, 23, 59, 59);
            break;
        case 2:

            endDate = new DateTime(int.Parse(year), i, 28, 23, 59, 59);
            // TODO: Leap years
            break;
        default:
            endDate = new DateTime(int.Parse(year), i, 31, 23, 59, 59);
            break;

     }
}

But further down in my code, I was doing something else with the DateTime class and I spotted it has a DaysInMonth function. You give it a year and a month (both ints), and it calculates the number of days in the month for you, and deals with the leap years that I hadn't got round to doing. Which means I can collapse my for down to:


for (int i = 1; i < 13; i++)
{
    DateTime startDate = new DateTime(int.Parse(year), i, 1, 0, 0, 0);
    DateTime endDate = new DateTime(int.Parse(year), DateTime.DaysInMonth(int.Parse(year), i), 30, 23, 59, 59);
}

Smaller code for the win!


EDIT: I just looked DaysInMonth up on MSDN and I'm surprised to discover it's been in the Framework since .NET 1.0!

Saturday 14 August 2010

A Good Day

Yesterday had an inauspicious start when the alarm went at 6am. I woke my wife up (again) when getting dressed. And when I got to the station I didn't have time to go to the shop and get a paper to read on the train.

But then...

The ticket inspector had an unexpected sense of humour.
A totally hot woman sat next to me on the train.
I wrote a StackOverflow answer on the hateful editor on my phone. 
And it was accepted.
Getting off the train I bumped into an ex-colleague I haven't seen for four or five years.
I got to spend the whole day getting my geek on watching ScottGu present on VS2010, ASP.NET 4, EF4 and MVC...

Amusingly, as I was waiting outside the cinema an American girl walked past and I heard her say 'must be a premiere' - I wonder how she'd have reacted if I'd told her we were all waiting to see a man from Microsoft...

VS2010 and ASP.NET 4
The first session was on what's in VS2010 and ASP.NET 4. As I've been using VS2010 since April I wasn't sure just how much I'd get from this session - the answer was, obviously, loads. 
I've already been using the HTML snippets, but now I know that there's a setting where I can turn off the requirement for an angle bracket before VS offers to complete the tag for me. What I didn't know is that there's a set of snippets for JavaScript as well. And a set for jQuery
We all learned that Scott doesn't like regions round his privates - cue much sniggering, I'm not sure it means quite the same thing in the States. But the learning point was that if you like regions done one way and your team mate prefers another, you can have regions that are private to you and won't show up when your colleague opens the file in VS. Ctrl + M, Ctrl + K is the keystroke to create one of these. 
Someone asked if there's a way to label these regions, to which the answer is no, however someone else pointed out that if you put a comment at the top of the region, it can work as a label when you hover over the collapsed region.
I picked up a bundle of new shortcut keys.
Collapse all regions - Ctrl + M, Ctrl + O
Incremental Search - Ctrl + I
Navigate files - Ctrl + Alt + Down Arrow
Navigate to - Ctrl + ,
View Call Hierarchy - Ctrl + K, Ctrl + T

Scott demoed some of the debugging features in VS2010, including pinning of watched variables, conditional breakpoints where the debugger only stops on a certain Boolean condition. And trace points, which allow you to write debugging messages to a TraceListener - optionally you can also continue executing your code, which neatly handles debugging a multi-threaded situation where breaking into the debugger hides the bug you're actually trying to find (the Heisenberg uncertainty principle in action!).
Scott showed how to use the ASP.NET Routing module in WebForms (the same one as used in ASP.NET MVC), and also showed off some of the deployment features, especially the Transforms which allow you to generate custom web.config files for different environments. Scott also told us that in the next couple of weeks there will be a new hosting gallery appearing on http://asp.net, which will allow you to search for a web host based on features they support.

MVC2 & EF4
I've seen a number of sessions in the last year on MVC and Entity Framework, but this was the first time I actually felt I was starting to 'get' it. I should have Scott sat next to me at work, think how much more productive I'd be!
Due to popular demand (and some well-publicised issues with the registration system for the day), Scott built a system based around developer events. For this session Scott started with a database, and built an entity model from it, then showed some of the features in MVC for displaying and editing data from the model. Highlights for me were the ease of allowing client-side validation - <% HTML.EnableClientValidation %>. That's it, one line of code!I was also very impressed with the scaffolding feature that allows you to build an editor page really quickly for a model. Whereas previously, you'd have written something like <% Html.TextBoxFor(fieldname) %> and the page will output a text-type INPUT tag (where field name is a string value), you can use the scaffolding to say <% Html.EditorFor(fieldname) %>, and the page will output a field appropriate to the data type of the field - a textbox for a string field, a checkbox for a Boolean field etc. And you can take this a level further - if you write <% Html.EditorFor(model) %>, ASP.NET iterates over the class and outputs the set of controls necessary to display and edit all the fields in the class - seriously cool.
In a large application, the number of controllers and views can grow so large as to make it difficult to pick a particular one out of the clutter, so Scott demonstrated how you can split an application up into Areas which allow you to group sets of controllers and views together to make it more manageable. Finally in this session Scott showed off some of the unit testing features. This included the gems that the 'Do you want to create unit tests' dialog when you create a new project is referred to as the 'Guilt' dialog, and the 'No I don't want to create unit tests' radio button is known as the 'I suck' button.

Windows Phone 7
After lunch, Scott took a (well-deserved) break and handed over to Mike Ormond to talk about Windows Phone 7. There are two programming models available for WP7, one in Silverlight and one in XNA. The Silverlight model should be used for event-driven type applications, the XNA one is more suited for time-driven apps e.g. game. However both types of apps can use features from the other if necessary. Mike also talked about how applications are distributed to a device, however what wasn't completely clear to me was how, as a corporate developer, if I write an app to be used internally to the company, I distribute the app and whether or not I have to release it to the marketplace. I was, mostly, quite intrigued about the platform as a whole - maybe later in the year I'll look more closely into developing for it.

Web Futures
The final session saw Scott back and talking about a number of the things that should be released by Microsoft later in the year, including IIS Express, MVC3, code-first Entity Framework and Razor. Of these, the ones that interested me most are IIS Express, and code-first EF. IIS Express I'm looking forward to as it will allow us to locally test our SSL pages (it comes with a local certificate). Code-first EF was interesting, although having not done any EF work I don't really know how much difference it would make. Similarly with Razor, I haven't done any MVC so I couldn't really appreciate the differences. Finally Scott showed off some TDD and in ten minutes explained Dependency Injection. I've been reading odd bits around DI over the last year, but I can honestly say I picked up more in that ten minutes than I did over the preceding 12 months!

And then we went to the pub with Scott to interrogate him, in which:
I learned that Dependency Injection and Inversion of Control are (more or less) the same thing. 
We were all amazed at how much of Microsoft ScottGu runs.
I learned the year the HTML 4 spec was ratified, though Dave Sussman says I can't tell anyone this.

It was A Good Day.

Thursday 12 August 2010

Data does not exist in the namespace Microsoft.Practices.EnterpriseLibrary

I started to build a new application this afternoon. It's nothing complicated, it just needs to read all the data for the forum on our Intranet and write it into flat files so we can archive it somewhere on our new improved Intranet. I fired up Visual Studio and knocked up a UI - basically it has a Start button and a number of progress bars. Switching to the code, I added a reference to the Enterprise Library 4.1 Data Access Application Block and wrote some code to read the data. Having got to the first point where I wanted to check that things were going more or less as I wanted them, I hit F5 to build and run the application.
The type or namespace name 'Data' does not exist in the namespace 'Microsoft.Practices.EnterpriseLibrary' (are you missing an assembly reference?)
Er, huh? I hit Rebuild with the same result. 
I checked that I'd added the block - yep, there it was in my project References. 
Rebuild. No joy. 
In the immortal words of Kenneth Williams, "stop messing about". I actually fired up Explorer and browsed to the DLL under my Program Files folder to ensure it was there.
Still no joy...

And then I had a flash of inspiration. The default .NET Framework version for the application was set to '.NET Framework 4.0 Client Profile' - what if that was causing a problem? That's caught me out before when I've been playing with MEF stuff. I changed it to the .NET Framework 4.0 full profile, hit Rebuild again and - success!

I solved my problem, but I'm sure I can't be the only one who's run into this one. It's trivial for me to solve because this application will only ever run on my laptop, but for someone who wants to use the Enterprise Library but also needs a minimal footprint when their app is installed, the two things become mutually incompatible. I can't help feeling that when you add a reference by browsing to a DLL, as I did, that Visual Studio should do a bit of inspection on the DLL and warn you if it's incompatible with the framework version you're currently using.

Thursday 22 July 2010

AppFabric Goes South(ampton)

(Very!) Belated thanks to the good developers of the NxtGen user group in Southampton for having me down last week to give my Developers Guide to Distributed Caching with Windows Server AppFabric talk. Despite a horrible journey round the M25, I had a really good time - I felt the session went well, the technology didn't let me down, and there were some really good and interesting discussions during the session and afterwards in the pub. It was also good to put a few faces to Twitter names!

Sunday 13 June 2010

AppFabric Goes to Ireland

Last week I gave my Distributed Caching with Windows Server Appfabric talk at EpiCenter, the Irish Software Show, at Trinity College in Dublin. My audience was a little, ahem, disappointing, particularly in the week that AppFabric was officially announced and released, since I only had one audience member, Mark Needham of Thoughtworks, who was presenting in the afternoon. I also had technical troubles with AppFabric again - clearly in a previous life I seriously pissed off the demo gods. I've now torn down my AppFabric demo infrastructure to rebuild it - this also gives me a chance to recompile my demos with the release version of AppFabric - I've been using the Release Candidate.

My slides from EpiCenter can be seen on Slideshare, and my demo code is downloadable here.

Tuesday 8 June 2010

Windows Server AppFabric is out!

As announced at TechEd yesterday, v1 of Windows Server AppFabric was released to the web at the weekend (though like the Release Candidate, I found out the Chris Alcock's excellent Morning Brew blog). You can download it directly here, or through the Windows Platform Installer. There's an installation guide here. If you've been using the Beta 2 Refresh release, the installer will allow you to upgrade from this to the release version - there are details here.

Additional coverage:
Official announcement from the AppFabric blog




The Irish Software Show

It's the Irish Software Show this week! There are 80 sessions taking place from top speakers including Craig Murphy, Jon Skeet, Alan Dean and many others. And also, ahem, me.

I'm doing my session on Distributed Caching with Windows Server AppFabric tomorrow, Wednesday 9th June. I shall also be attempting to whip the crowd into a frenzy before Jon Skeet does his first session - yes, I'm Jon Skeet's warm-up man!

If you haven't got tickets for the show yet, it's not too late! And even better, the organisers have very kindly allocated some concession tickets to me: if you go to my page on the EpiCenter website, you can get up to €90 off the price of your ticket! And I'll see you tomorrow!

Friday 28 May 2010

What's New in the AppFabric Release Candidate




The Windows Server AppFabric Release Candidate was, well, released last week. Here's a quick look at changes from Beta 2.

What's New in PowerShell
Possibly the most visible change is the return of the Start Menu item for Powershell with the AppFabric module pre-loaded.












This fires up the Powershell console and runs 'Import-Module DistributedCacheAdministration' from the command-line, with the No-Exit switch to keep the console open. However it seems (at least on my Windows 7 machine) that there is something not quite right with this, as I now have to Exit from Powershell twice before the console actually closes. I've checked this on a VM running Windows Server 2008 as well as my Windows 7 laptop and it behaves the same on both platforms. Usefully, however, it also runs 'Use-CacheCluster', which if you're anything like me, saves you trying to run a cache command, then running Use-CacheCluster, then running your original command again.











I'm slightly disapppointed that the cachehelp command hasn't made a reappearance, so overall for Powershell I think I'll stick with my customised profile for importing the AppFabric commandlets.

What's New in Licensing
Err, nothing. There is no Go-Live license for the Release Candidate, although to be fair you might as well now wait another few weeks for the v1 release.

What's New in the Caching API
Again, nothing (that I can see), although since Beta 2 was the feature-complete release, it would be wrong to be making changes now.

Thursday 20 May 2010

AppFabric Goes North!

Thanks to NEBytes for having me up to speak last night (and thanks to Andy (and Tammy :-) ) for putting me up). I ran my AppFabric distributed caching session, and for the first time nothing broke! Lots of performance problems though, caused by trying to run too many VMs on not enough memory. I think when I get home I'll review my demos: I want to run them all in one VS project to make it easier to swap between them as I'll just be able to run up one Cassini instance that'll contain all the demos. I was also thinking last night I might change the Regions/tagging demo so I get the objects from the database as required and then cache them in a lazy style. Watch this space.

I missed the first half of Jonathan Noble's session on Powershell 2.0, but I was quite impressed with what I did see. My use of Powershell can be described as 'fledgling' at best (even though it's used in managing AppFabric clusters and caches), so it was instructive to see it really put through it's paces. The remoting tools built into Powershell 2.0 look particularly impressive, it's made me think about how we manage our web servers at work and whether we should be using Powershell from our desktops instead of RDPing onto the servers and then using the IIS MMC.

I'd have liked a bit more time to look round Newcastle as it's somewhere I've never visited - maybe next time. I did get to drive past the Angel of the North, which was disappointingly somewhat less impressive than I'd anticipated. And this morning on the way back I got to see (if only on the horizon) the Middlesborough Transporter Bridge! (Thanks for the A19 tip Andy!)

Wednesday 28 April 2010

Rebuilding CacheHelp

Ron Jacobs blogged yesterday about using the AppFabric Beta 2 Refresh and the fact that the cachehelp command seems to have disappeared. If you rely on cachehelp as much as I do, fear not! To paraphrase the start of The Six Million Dollar Man, 'we can rebuild it'...

Powershell includes a Set-Alias command, which we can use to create aliases for existing commands e.g. Set-Alias nc New-Cache. Ron helpfully provided the Powershell command we need to retrieve the AppFabric commands - Get-Command -module distributedcacheadministration - BUT you can't create an alias for a whole command-line with parameters, only for an individual command.

Fortunately we can get round this by creating a Powershell function which wrappers the commandline:
function getVelocityCommands
{
    Get-Command -module distributedcacheadministration
}

Now we can use Set-Alias GetCacheHelp getVelocityCommands to create an alias which calls the function. And we're done!

Almost...

Aliases and functions are session-based - once you close down Powershell, you'll lose them. To make them persistent, you'll need to add them to your Powershell profile. There's a great tutorial here on creating Powershell profiles. Too much work? Then download this profile, which imports the AppFabric commands and creates the cachehelp alias for you.

Monday 26 April 2010

AppFabric For .Net 4.0

So a fortnight ago .NET and VS2010 were released, and shortly after that I tried to install the AppFabric Beta 2 release on my laptop. No go - Beta 2 has a dependency on the .NET 4 Release Candidate and will not install on the .NET 4.0 RTM release. I emailed Ron Jacobs (who has made the mistake of being associated with AppFabric and being contactable) about this and asked when we'd see a release that ran on the .NET 4.0 RTM release. He answered me and then wrote up this blog (and when he talks about emails rolling in, it's mine he quotes so I'm slightly suspicious of how many he really got about this), which says that .NET developers who want to use AppFabric will have to stay on the .NET 4.0/VS2010 RC versions until an unspecified time between now and the end of June when AppFabric will RTM. I can't say that I was hugely impressed with this:

So I was quite surprised today to look at Alvin Ashcraft's Dew Drop and find:
Which appears to be AppFabric Beta 2 rebuilt for .NET 4.0 RTM. I haven't tested it yet, but I've installed it and can confirm it installs OK onto a Windows 7 machine with .NET 4.0 RTM.

There's nothing yet about this on either Ron Jacob's blog, the Velocity blog or the .NET Endpoint blog. And I'd like Microsoft to explain their change of heart - right now, I'm interpreting it as being that AppFabric may miss it's RTM deadline of 30th June. But someone should feel free to tell me different.

Tuesday 20 April 2010

Building A PageStatePersister With AppFabric

One of my favourite demos to do at user group sessions is to show off how you can use the SessionPageStatePersister to store page state information (Viewstate and Controlstate) on the server in Session state instead of round-tripping it to the client. But yesterday it occurred to me that you could do the same thing quite easily with AppFabric caching*.

ASP.NET has shipped with two page state persistence mechanisms since ASP.NET 2.0 was released - HiddenFieldPageStatePersister, which is the one used by default and produces those <input id="__VIEWSTATE" type="hidden" value="AnEnormousBase64EncodedTree" /> tags that we all hate so much, and SessionPageStatePersister, which instead stores the state on the web server in Session state and cuts out the roundtripping. To use the SessionPageStatePersister you need to write an Adapter class and a .browser file:

using System.Web.UI;
using System.Web.UI.Adapters;

namespace Adapter
{
    public class Adapter: System.Web.UI.Adapters.PageAdapter
    {
        public override PageStatePersister GetStatePersister()
        {
            return new SessionPageStatePersister(this.Page);
        }
    }

<browser refID="default">
    <controladapters>
        <adapter controltype="System.Web.UI.Page">
            adapterType="Adapter.Adapter" />
    </controladapters>
</browser>

SessionPageStatePersister is built into the .NET Framework, so our adapter can just new it up and return it in the GetStatePersister function. If we want to build a PageStatePersister with AppFabric, however, we've got a bit more work to do. We need a class that inherits from PageStatePersister so we can implement the Save and Load methods.

using System.Web.UI;
using System.Web.UI.WebControls;

namespace AppFabricPageStatePersister
{

    public class Persister : System.Web.UI.PageStatePersister
    {
        public Persister(Page page) : base(page)
        {
        }


        private const string HiddenFieldId = "StateIdHiddenField";


        public override void Load()
        {
            // Read page's incoming state Id from hidden field
            string stateIdString = Page.Request.Form[HiddenFieldId];


            Pair cachedState = (Pair) CacheHelper.Get(stateIdString);


            ViewState = cachedState.First;
            ControlState = cachedState.Second;
        }


        public override void Save()
        {
            Pair statePair;


            // Build a Pair from the Page's View- and ControlState
            statePair = new Pair(ViewState, ControlState);


            // Generate a new ID to use as the key for storing in the cache
            Guid stateId = Guid.NewGuid();


            // Put the Pair in the cache
            CacheHelper.Put(stateId.ToString(), statePair);


            // Write the key out into the page in a hidden field so we can get it back later
            Page.ClientScript.RegisterHiddenField(HiddenFieldId, stateId.ToString());
        }
    }
}

CacheHelper is an abstraction over AppFabric so my Persister class isn't cluttered with calls to the AppFabric objects:

using System.Web.Configuration
using Microsoft.ApplicationServer.Caching;

namespace AppFabricPageStatePersister
{
    class CacheHelper
    {
         public static object Get(string Key)
         {
            DataCacheFactory factory;
            DataCache cache;
            string cacheName;
            factory = new DataCacheFactory();
            cacheName = WebConfigurationManager.AppSettings["StatePersistenceCacheName"].ToString();
            cache = factory.GetCache(cacheName);
            return cache.Get(Key);
       }

       public static void Put(string Key, object Value)
       {
            DataCacheFactory factory;
            DataCache cache;
            string cacheName;

            factory = new DataCacheFactory();
            cacheName = WebConfigurationManager.AppSettings["StatePersistenceCacheName"].ToString();
            cache = factory.GetCache(cacheName);

            cache.Put(Key, Value);
        }
    }
}

The adapter is straightforward - like the SessionPageStatePersister adapter, all it needs to do is return a new instance of AppFabricPageStatePersister, and the .browser file just needs to point at AppFabricPageStatePersister.Adapter.

namespace AppFabricPageStatePersister

{
    public class Adapter : System.Web.UI.Adapters.PageAdapter
    {
        public override System.Web.UI.PageStatePersister GetStatePersister()
        {
            return new Persister(this.Page);
        }
    }
}

<browser refID="default">

    <controlAdapters>
        <adapter controlType="System.Web.UI.Page"
adapterType="AppFabricPageStatePersister.Adapter" />
    </controlAdapters>
</browser>
Simples.

Download this demo code: C# VB

* Yes, I know you could put your Session state in AppFabric and continue to use the SessionPageStatePersister but I'm assuming you can't/don't want to use Session state.

Monday 29 March 2010

Book Review: Beginning ASP.NET Security

If you're doing web development with ASP.NET, you need this book. Simple as, end of.

And I'm not just saying that because I'm mentioned in it (page 235 for those of you playing along at home).

When I heard Barry was writing a book, I knew it'd be a good one to get, having seen Barry speak on security topics at several user groups and conferences. And now I've read it I can see it's going to become one of those books that never gets put away neatly on a shelf, it's always going to be open on someone's desk. Experienced developers shouldn't be put off by the 'Beginning ...' in the title, this book is for every ASP.NET/MVC/Silverlight/WCF developer who has security concerns. Which should be all of you.

The approach of the book is task-oriented; each chapter describes one or more vulnerabilities that a web developer may come across, and then describes how to mitigate against them. I started learning right from the first technical chapter, which covers validation: there are several things I've picked up about the ASP.NET validator controls, including how to validate input data against a .NET data type and how to write a custom validator. Cross-Site Request Forgery isn't quite what I thought it was either. Of course, things like Cross Site Scripting and SQL injection are covered, but also some of the more obscure vulnerabilities that are traps for the unwary; I'd never heard of things like traversal attacks and XPath injection. There is an excellent chapter on encryption covering all the options available in the .NET Framework for encypting and decrypting your data, although I'd have liked to see for each type of encryption some more suggested scenarios in which each method is appropriate. Coming right up-to-date Barry also covers how to use external authentication providers like OpenId, *ahem* LiveId and Windows Identity Foundation, and finally has a whole chapter on securing MVC applications, lest the lack of Viewstate and auto-encoding <%: tags leads MVC developers to believe there's nothing more they need to do.

Right, I'm off to do a security review of all our live sites. I may be some time...

Wednesday 3 March 2010

What's New in AppFabric Caching Beta 2

Typical - just as I get an AppFabric Beta 1 caching cluster up and running for Edge UG this month, they release Beta 2!

This is, by all accounts, now a feature complete release for v1.0 with the RTM expected in Q3 this year. There is, however, no Go Live licence here, unlike Visual Studio. Let's take a look at AppFabric B2 and see what's changed (from a caching perspective)...

What's New in Installation
First of all, this release is aligned with the Release Candidate of .NET 4.0 and VS2010, so the dependency on the .NET Framework is moved up from the beta to the .NET 4.0 Release Candidate. Note that if you're removing the .NET 4.0 Beta in order to install AppFabric, you need to do this in Control Panel|Programs and Features, and uninstall the .NET 4.0 Framework Extended first, then the the .NET 4.0 Client Profile.

The installer seems to have had quite a bit of time spent on it for this release.
The set of features to install is largely the same as we saw in Beta 1, with the addition of an administration piece for the Dublin workflow component.

Post-installation, the AppFabric caching service has been renamed and no longer refers to the Velocity codename; it also now is not marked as a CTP (unlike the caching service in Appfabric Beta 1 which still showed as CTP4).

Installation and configuration have been decoupled into two separate wizards, which should make it possible to reconfigure a cluster without having to un- and re-install.The configuration wizard can be started at the end of installation, or separately from the Start menu.


What's New in Configuration
As before when configuring the caching piece you have to decide whether to store configuration information in SQL Server or using XML and a network share. There's still no guidance on when you should use one or the other, although included in this release is a comprehensive help file.

Selecting the SQL Server provider and clicking the Configure button opens this sub-dialog where you can build up the connection string to the configuration database. It's now explicit that if you enter the name of a database that doesn't exist and select the 'Create...' checkbox then the configurator will go and create the database for you. If you're adding a server to an existing cluster, then the 'Register...' checkbox is the one to select; if you unselect both checkboxes you lose the ability to enter any connection string information. However there seems to be a slight bug in that whether you create a new database from scratch or register a server to an existing database, when you return to the main configuration screen you can still choose whether you are creating a new cluster or joining an existing cluster.
As before, the configurator allows you set the size of the cluster to optimise the clusters' performance. The help file states that 'once you set the cluster size during configuration, you cannot change it later', however it's unclear how this fits in with the ability to re-run the configurator from the Start menu.

As I run my Velocity VM cluster with Windows Firewall disabled, I'm pleased to see that the Cache Node configuration page now detects when the firewall is disabled and accordingly disables the firewall exceptions checkboxes. This is a change to Beta 1 where the Velocity installer log would register a warning if the firewall was disabled.

What's New in Powershell
In a change from previous installs, there doesn't seem to be a Velocity Administration Powershell console installed by default; to access the Velocity Powershell commands you need to run up Powershell and then run 'import-module DistributedCacheAdministration'. Or you can add it to your Powershell profile - run 'get-help profiles' for details on doing this.
Looking at the list of Powershell commands available it seems that, unforgivably, there's still no commandlets for managing regions.The Install-Data and Install-Bits cmdlets that were in Beta 1 have disappeared.

A new feature is that it seems you can now use Powershell on any server with the Velocity cmdlets installed to manage any Velocity cluster, by using the 'Use-CacheCluster' cmdlet with a connection string to a configuration store (though the documentation talks about a connection string which implies this only works with the SQL Server provider). This cmdlet sets the context of subsequent commands e.g. Start-CacheCluster, Restart-CacheCluster. This enables you to manage multiple clusters from a server that isn't in any cluster. If you're running Use-CacheCluster on a server that is inside a cluster and has Cache Administration (from the installer) set up, you don't need to use any parameters, the current cluster is implied.

What's New in Client Configuration
The assemblies that you need to add to a project to use Velocity have been renamed, to Microsoft.ApplicationServer.Caching.Core.dll and Microsoft.ApplicationServer.Caching.Client.dll (in Windows\System32\AppFabric). The namespace has changed again, to Microsoft.ApplicationServer.Caching. And the requirement to also reference the Fabric assemblies has been removed, so there's only two references to add which makes the whole thing seem much cleaner.
The MSDN article on setting up the client environment states that there is a problem with referencing these DLLs as Visual Studio is unable to browse to Windows\System32\AppFabric, and that you need to hand-edit the project file to include these references. This seems to be incorrect, as I've just done it - I suspect that this may be due to the fact I'm running Visual Studio under an account which is an administrator on the server and thus has access to everything.
A couple of the old annoyances when writing client code are still there:
  • DataCacheFactory.GetCache is still not a static method, you still need to new up a DataCacheFactory.
  • Some of the code around using DataCacheServerEndpoints seems to have been refactored a little bit, but it still runs on an array, not a List(Of DataCacheServerEndPoint). But you can, of course, still get round this by using a List(Of DataCacheServerEndpoint) and then calling .ToArray on it.
That's all I've discovered that's new (for now), but I'll post more updates as I discover things!

Saturday 20 February 2010

A Developer's Guide To Velocity on tour!

Following on from Liam's recent tour dates blog,I thought I should do something similar...

First of all I need to offer belated thanks to NxtGen Manchester for having me up to speak in January. I had a good time even though something went wonky in my VMs while I was running my demos that morning which meant I couldn't run the demos in the evening. I hope everyone still got an appreciation of the capabilities of Velocity.

I'm running this session again at Edge UG at Microsoft in London on 17th March - visit http://edgeug.net to sign up. I may be running it at DDD Scotland if I've been voted in. Subject to agreement on dates it'll be at NxtGen Southampton in June. I've also been talking to NxtGen Cambridge and NEBytes about doing it for them over the summer.
UPDATE: Well I didn't get voted in for DDD Scotland, but there'll be another opportunity to vote for me at DDD Southwest.And I now have a confirmed date for NxtGen Southampton - 24th June.

Sunday 7 February 2010

What I Learned At DDD8

First thing on Saturday morning my Twitterstream was full of sleepy geeks converging on Reading - yes, it was time once again for DDD at Microsoft. DDDs are free one-day conferences where all the content is from the UK Microsoft developer community - Microsoft speakers are not allowed to speak, although they usually come just to hang out. The community also decide the sessions that form the agenda by voting on submissions. I was lucky enough to speak at DDD7, but my session didn't make it into DDD8 (which was for the best as hardware failure meant I wouldn't have been able to do any demos). They're also a good networking event - a useful addition this year was to have people's Twitter names on their badges, which meant that if, like me, you follow a number of people you've never met, you could start to spot them and say hello. In fact, at one point I thought 'this is just a social thing with some technical content tacked on'!

Once I was at Microsoft and checked in, the first person I saw was Simon Harriyott, who I met for the first time the preceding Thursday at Barry Dorrans' leaving drinks. Of which more later. As I was getting my sausage sandwich and coffee, I also bumped into VBUG Chair Tim Leung and had a quick catch-up with him before it was time to head into the first session of the day...

Barry Carr - Contractual Obligations: Getting Up and Running With Code Contracts
I walked into this session and pleasingly got a seat next to virtualisation guru and all-round good guy Liam Westley, and behind Guy Smith-Ferrier and Gary Short. I picked this session as it sounded to be similar to some work that was done at my last company, and it proved to be a very interesting talk. The concept of code contracts stems from some work done by the not-yet-dead Bertrand Meyer, father of the Eiffel programming language. Contracts allow you to specify pre- and post-conditions on methods, functioning like Asserts. One of the most interesting demos was where Barry stepped through some code, which had both pre- and post-conditions declared at the start of a function followed by the body of the function; as Barry stepped through the code Visual Studio seemed to be jumping around the code instead of following the flow of code as written, due to the way that Code Contracts amends the IL that your .NET code outputs. However the highlight of this talk was probably when one delegate had the temerity to ask a question; his reward was a USB stick, however Barry threw it to him unintentionally hard and nearly took him out!

I followed this with ...
Neil Robbins - Hello Document Databases
Neil said up front that he's a new speaker and that this was his first DDD session, and proceeded to give a blinding talk on NoSQL and CouchDB. CouchDB (and its' GUI, Futon) are all based around a mantra of Relax, which several of us shouted out from the audience at certain points when Neil got tied up by some Linuk case-sensitivity issues :-) Neil's demos were done with CouchDB running on Ubuntu, which was a slight disappointment for me as it effectively means CouchDB is something I won't be able to run at work; Neil's comment is that the installer for CouchDB on Windows is only a beta. Which is a shame as CouchDB looks like exactly the kind of technology we could do with at work for asset management software - we've had several conversations recently around the Entity-Attribute-Value pattern, which seems to be the major problem that CouchDB solves.
Andy Gibson - Web Application Testing with Selenium
This was an introduction to using Selenium, which is something I need to look into further, however I have to confess to too much Twittering and not enough paying attention in this session, particularly after John Nolan tweeted that he needed some water (Memphis was by now getting seriously warm) and minutes later Craig Murphy brought some in for him!

Simon Sabin - Entity Framework - How to Stop Your DBA Having a Heart Attack
I went into this session intending to pick up some knowledge about the Entity Framework, as I basically don't have any and one of my colleagues is intending to use it on his next project.But for that, and for me really, it was the wrong session. I still took some points away from it though, the key one being that although the SQL produced by the Entity Framework can look like it won't perform well, you can spend a lot of time trying to optimise it yourself but get only comparable results. Another good takeaway concerned the DATE datatype in  SQL Server 2008 - traditionally when trying to restrict results to a single date, we've used a SQL BETWEEN clause with the bounds set to midnight and 23:59 for the date in question; in SQL 2008 we can cast DATETIME values to DATE and just search for rows where the date is the date in question.
Oh, and for my personal future reference it's pronounced Say-bin.

Barry Dorrans - A Developers Guide To Encryption
And on to the last session of the day, and Barry's last DDD presentation before leaving the UK to go and work for Microsoft in Redmond. I first met Barry back at DDD1 and I've seen him speak a few times since then, and he's always been good. However, I already knew that his session was going to have some disruption, having had a chat with Phil Winstanley about it at the aforementioned leaving drinks. And also having provided to Phil and Craig Murphy, the organisers, a video of a rather younger Barry when he was on The Crystal Maze. And we weren't disappointed, either by the session (very good) or the disruptions (very funny). Barry wasn't too fazed by the videos that kept appearing on the big screen (or by Jon Skeet and others pointing out both mistakes in his code and typos on his slides). It started with coverage of hashing (which is NOT encryption), and then proceeded to show symmetric and asymmetric (private/public key) encryption, X.509 certificate encryption and XML encryption. I think everyone will remember Barry's key point about symmetric encryption keys, which can become diluted the more they are used for: Barry's message is keys are like condoms, don't re-use them. The only thing I would have liked to see would have been for each level of encryption the kind of data you might protect with it e.g. the correct level of encryption for storing, say, credit card data. 

All in all another excellent day at Microsoft, I should like to say a big thank you and well done once again to the organisers, looking forward to DDD9!

Thursday 28 January 2010

Extensible Output Caching with Velocity

This morning Scott Gu posted an article on his blog about the extensibility points now built into output caching in ASP.NET 4.0. Steve Robbins said to me that it looked easy to wire up Velocity, and I was pleased to see that when ASP.NET 4.0 ships there will be a set of samples showing how to use Velocity as an output cache provider, however since Scott said that writing an output cache provider is just a case of inheriting from System.Web.Caching.OutputCacheProvider and overriding four methods, I decided to have a look at it at lunchtime.

And it does seem remarkably simple - here's my code:
Imports Microsoft.Data.Caching
Public Class VelocityOutputCacheProvider
    Inherits System.Web.Caching.OutputCacheProvider
Private Const cacheName As String = "VelocityOutputCache"
Private mCache As DataCache
Public Sub New()
    Dim factory As DataCacheFactory

    Try
        factory = New DataCacheFactory

        mCache = factory.GetCache(cacheName)
    Catch ex As Exception
        Throw
    Finally
        factory = Nothing
    End Try
End Sub

Public Overrides Function Add(ByVal key As String, ByVal entry As Object, ByVal utcExpiry As Date) As Object
    Try
        mCache.Add(key, entry, (utcExpiry - DateTime.UtcNow))
    Catch ex As Exception
        Throw
    Finally
    End Try
End Function

Public Overrides Sub Remove(ByVal key As String)
    Try
        Call mCache.Remove(key)
    Catch ex As Exception
        Throw
    Finally
    End Try
End Sub
Public Overrides Function [Get](ByVal key As String) As Object
Dim cachedObject As Object
    Try
        cachedObject = mCache.Get(key)
        Return cachedObject
    Catch ex As Exception
       Throw
    Finally
    End Try
End Function
Public Overrides Sub [Set](ByVal key As String, ByVal entry As Object, ByVal utcExpiry As Date)
    Try
        Call mCache.Put(key, entry, (utcExpiry - DateTime.UtcNow))
    Catch ex As Exception
        Throw
    Finally
    End Try
    End Sub
End Class

The only thing I'm a little fuzzy on is what object the Add method should return. It's slightly awkward that the Velocity Cache.Add method takes a TimeSpan parameter where the OutputCacheProvider passes in a point in time, so I've calculated a TimeSpan by subtracting the current time from the passed-in Date.
 
Something that's slightly unclear is how this would behave in a server farm. It depends whether each server maintains it's own set of cached pages, or the cached pages are common and available to all servers. If the latter then this would be a truly awesome boost to scalability since for any given web page only the first server that picked up a request for a given URL would need to compile it - other servers in the farm would then be able to pick up the cached copy and return it to the client.

Update: When the Add method is called, you don't need to return anything, just put the object into the cache and ASP.NET takes care of the rest. You get a warning that the function doesn't return anything but this can be ignored.

Wednesday 6 January 2010

Installing AppFabric Caching Beta 1, Part 4

I'm pleased to report that I've (at last) had a measure of success with the AppFabric installer :-)

I mentioned in my last entry that I'd posted on the MSDN AppFabric Caching forum about the problems I'd been having with the installer. I also made two of my installation logs available. I'm indebted to Rahul Kaura from Microsoft, who pointed out that these were AppFabric general installation logs and steered me towards the cache-specific installation logs. These logs are found in the same place as the AppFabric logs i.e. your %TEMP% folder, are called DistributedCacheAppServerConfig(DateTime).log and I've found them invaluable in diagnosing and fixing installation problems.

So what were the problems I was having? From reading the log they seem to be largely around permissions to the Registry:
2010-01-06 11:52:52, Info DCACHE Adding access for NT AUTHORITY\NETWORK SERVICE on registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft Distributed Cache\Version



2010-01-06 11:53:16, Error DCACHE System.InvalidOperationException: This access control list is not in canonical form and therefore cannot be modified.
at System.Security.AccessControl.CommonAcl.ThrowIfNotCanonical()
at System.Security.AccessControl.CommonAcl.AddQualifiedAce(SecurityIdentifier sid, AceQualifier qualifier, Int32 accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType)
at System.Security.AccessControl.DiscretionaryAcl.AddAccess(AccessControlType accessType, SecurityIdentifier sid, Int32 accessMask, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
at System.Security.AccessControl.CommonObjectSecurity.ModifyAccess(AccessControlModification modification, AccessRule rule, Boolean& modified)
at System.Security.AccessControl.CommonObjectSecurity.AddAccessRule(AccessRule rule)
at Microsoft.Data.Caching.InstallConfig.Program.SetResetLocalPermissions(Boolean grant)
at Microsoft.Data.Caching.InstallConfig.Program.PostConfigServiceInstallSteps()
at Microsoft.Data.Caching.InstallConfig.Program.Install()
at Microsoft.Data.Caching.InstallConfig.Program.Main(String[] args)


2010-01-06 11:53:16, Error DCACHE Unexpected Error: This access control list is not in canonical form and therefore cannot be modified.


2010-01-06 11:53:16, Info DCACHE Configuration failed, Rolling back...

which is sort of annoying as I've been running the installer under an account that is a Domain Administrator, and the Domain Admins group is part of the Administrators group on each of my cache servers. The solution was to add the account I'm using to install AppFabric to the ACL for HKEY_LOCAL_MACHINE with full permission.

The installer still reports that it fails to configure AppFabric, but this is because the log includes a Warning that the Windows Firewall is disabled, which I'm reasonably sure I can ignore.

So, I now have an AppFabric caching cluster with three servers. Onward to actually using it!