Using Fluent Validation with ASP.NET MVC – Part 2: Unit Testing

In my previous blog post I looked at the basics of setting up and using FluentValidation with ASP.NET MVC.  This time around we will be having a look at unit testing with FluentValidation.  There are a few approaches to do validation of your model or view model objects using data annotations.  One of the ways to do this is by using the approach described by K. Scott Allen in this blog post.  FluentValidation makes the process of unit testing your validation errors quite easy.

Fluent Validation Helpers

The FluentValidation framework supplies us with a few helper methods to assist in testing validation rules which are located in the FluentValidation.TestHelper namespace.

public static void ShouldHaveValidationErrorFor<T, TValue>(this IValidator<T> validator, Expression<Func<T, TValue>> expression, TValue value)
public static void ShouldHaveValidationErrorFor<T, TValue>(this IValidator<T> validator, Expression<Func<T, TValue>> expression, T objectToTest)
public static void ShouldNotHaveValidationErrorFor<T, TValue>(this IValidator<T> validator, Expression<Func<T, TValue>> expression, TValue value)
public static void ShouldNotHaveValidationErrorFor<T, TValue>(this IValidator<T> validator, Expression<Func<T, TValue>> expression, T objectToTest)

Validating individual properties

These methods allow us to easily test each of the validation rules individually without the need to construct a complete test object to validate each time.  For example, our unit test to ensure that the username gets validated correctly for null values looks as follows:

[TestMethod]
public void ShouldHaveValidationErrorWhenNoUsernameIsSupplied()
{
    validator.ShouldHaveValidationErrorFor(x => x.UserName, (string)null);
}

As you can see we do not have to construct an entire test RegisterModel object, but just have to specify the property which we want to validate and the value we want to validate against.  The example above is a negative test and ensures that a validation error gets generated when a property value is not valid.  We can also test to ensure that no validation error gets generated when we pass a valid value:

[TestMethod]
public void ShouldNotHaveValidationErrorWhenUsernameIsSupplied()
{
    validator.ShouldNotHaveValidationErrorFor(x => x.UserName, "username");
}

Validating related properties

Lastly we can also pass in an entire object to validate, for example when we want to validate that the Password and ConfirmPassword properties match

[TestMethod]
public void ShouldHaveValidationErrorWhenPasswordAndConfirmPasswordDoesNotMatch()
{
    validator.ShouldHaveValidationErrorFor(x => x.ConfirmPassword,
        new RegisterModel
        {
            Password = "password1",
            ConfirmPassword = "password2"
        });
}

Validating an entire object

All the above helper methods test only for the case where we want to test for a validation error related to a certain property.  We  can also test to ensure that the entire object is valid or when we want to test for validation errors on the object level, i.e. validation errors which relate to the object as a whole and not to specific properties.  In such cases we can simply call the Validate method on our Validator which will return a ValidationResult.

The ValidationResult contains a property IsValid which indicates whether the object is valid, as well as an Errors property which contains a collection of errors when the object is not valid.  As an example we pass in a valid object, run in through the validation and ensure that the validation result is valid:

[TestMethod]
public void ShouldNotHaveValidationErrorsWhenValidModelIsSupplied()
{
    ValidationResult validationResult = validator.Validate(new RegisterModel
                                                            {
                                                                UserName = "username",
                                                                Password = "password",
                                                                ConfirmPassword = "password"
                                                            });
    validationResult.IsValid.Should()
                    .BeTrue();
}

In case you wondering about the manner in which I do the assertion, I am using the wonderful FluentAssertions class library in the example above.

Next time we will look at one of the main reasons I use the FluentValidation library, which is the ease with which we can do dependency injection.

As always, source code is located on Github at https://github.com/jerriep/MVC4ValidationUsingFluentValidation

Using Fluent Validation with ASP.NET MVC – Part 1: The Basics

One of the most popular ways to do model validation in the ASP.NET MVC  Framework is surely to use the built-in model validation features using data annotations.  This will probably work fine in most instances, but I prefer using the Fluent Validation library in my own projects mainly because of how easy it is to unit test validation rules, as well as the fact that I can split the validation rules completely from the underlying model.  Yes, I know you can unit test validation using data annotations as well without too much hassle, but when you need to inject dependencies into your validation rules, things can become a bit tricky.

In any case, as with many things in the software development world there is surely no correct answer as to which method is the best – it comes down to using what you are most comfortable with.  I will be doing a short series on using Fluent Validation with ASP.NET MVC 4, so if you are interested in using it in your own projects then read on.  In this blog post I will show you how to add the FluentValidation class library to your project as well as how to replace the existing data annotations validations with Fluent Validation.

 Integrating Fluent Validation in your project

Fluent Validation is available as a Nuget package, so to install it is as simple as searching for the Fluent Validation package in the Nuget Package Manager.  You can add the package named FluentValidation.MVC as that will install both the core Fluent Validation package as well as the ASP.NET MVC 4 extensions.

Capture

Replacing the existing Data Annotations validation

For this basic tutorial we will be taking the existing registration model and change it from using data annotations to using Fluent Validation.  This is what the standard RegistrationModel class looks like which is generated by the default ASP.NET MVC 4 Internet Application template:

public class RegisterModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

All of the validation rules in this class are placed in a new class called RegisterModelValidator.  For information on the type of validation rules which you can specify please refer to the Fluent Validation documentation on the Built In Validators.

public class RegisterModelValidator : AbstractValidator<RegisterModel>
{
    public RegisterModelValidator()
    {
        RuleFor(x => x.UserName)
            .NotNull();
        RuleFor(x => x.Password)
            .NotNull()
            .Length(6, 100);
        RuleFor(x => x.ConfirmPassword)
            .Equal(x => x.Password);
    }
}

This validation class is then linked to the RegisterModel class by specifying it in the Validator attribute:

[FluentValidation.Attributes.Validator(typeof(RegisterModelValidator))]
public class RegisterModel
{
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    public string ConfirmPassword { get; set; }
}

The final step is to hook up the FluentValidation class library to the ASP.NET MVC 4 validation framework.  To do this you simply need to make a call to the FluentValidationModelValidatorProvider.Configure() method inside your global.asax file.

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();

        FluentValidationModelValidatorProvider.Configure();
    }
}

Next time we will look at adding some unit tests for our new validation classes.  As always source code can be found on Github at https://github.com/jerriep/MVC4ValidationUsingFluentValidation

How TDD assists me

There are a lot of reasons why people suggest you should do Test Driven Development, and even though I was not a total convert right from the beginning, the practice is growing on me.  My situation is a bit unique from probably most developers out there, so while I buy into a lot of the common reasons why you should do TDD, there are a few unique advantages I gain from it.

Maybe a bit of my background first.  I have been a contractor most of my life, which allowed me to work on a whole range of different projects.  In the last year I work on a team for a large South African organisation who decided to make the shift to Agile methodologies, and the team I worked on was used as the guinea pigs to see if it could be introduced into the wider organisation.  Towards the end of last year I decided to make a big change: I sold all my belongings and now I am traveling the world writing my own software.  (You can read more about me travels on my blog Jeremia was a Bullfrog).

Even though I am now working by myself and for myself, a lot of the things I learned from Agile carried over and I am using it on a day to day basis.  One of those are TDD.  So what are the biggest advantages I derive from TDD?

1. Procrastination Buster

Like I said, I travel the world and write code.  I try and do this from exciting places, which means that I have a lot of things which can distract me from doing my work.  It is oh so very easy for me to procrastinate and find some other, much more exciting things to do.  So I use TDD as a procrastination buster.  Whenever I don’t want to work (but know I have to get some work done), I just start writing a failing unit test.  I then go through the process of getting the unit test green and move on to the next one.  Before I know it an hour of two has passed and I have done a lot of work to move my software product forward. It works so well for me that I sometimes have to force myself to get up from my computer and go see the world outside.

2. It enables me moved forward when I am offline

Working in exotic locations has its advantages, but one big disadvantage for me is that the internet connectivity is intermittent.  Right now for example I am working on Koh Tao, and island of the coast of Krabi, Thailand.  As wonderfully quiet as it is here my one big problem is that the internet connectivity is really bad.  This is an especially big problem for me as the application I am developing is working with social media (Facebook, Twitter etc.), so without internet connectivity this poses a bit if a problem for me.

How does TDD help me you may ask?  Mocks and Fakes, that is how.  I can develop large portions of my application using just unit tests, mocks and fakes.  It is of course not 100% foolproof, but I have gone days where I wrote massive pieces of functionality without ever connecting to the internet just by using mocks and fakes.  And each time, once I got to the point of connecting to the internet to test the functionality end to end, it worked basically without any problems.

3. It helps me design my application

This you will see in a lot of places where people list the advantages of TDD, but for me it is the one which was probably the most noticeable from the beginning and which I still notice every day.  For me TDD helps me to design a better application.  I feel that by writing the unit tests first I get a better understanding of what the actual code should do.  I also feel that it helps me design better classes, or when I notice a problem in my design I can go back and refactor without fear because I know the unit tests have go my back.

Of course I go along with a lot of the other advantages which people always hold up as reasons for why you should do TDD.  These 3 are just the ones that I find resonates with me the most in my personal situation.

Sign Up to notify when my application launches!

I am nearing the date when my application launches, so head on over to www.oneloveapp.com and if it sounds like something you may be interested in, please subscribe to the email list to be notified when the application launches.

Synchronising collections using ReactiveUI

With the announcement of ReactiveUI 4.5 and the fact that it now works with the Xamarin products as well, I have decided to give it a try and see if it gives me better cross platform capabilities than Caliburn Micro (which has no support for the Xamarin products at all).  My first task was to try and get my head around Reactive Extensions, and for that I found the website Introduction to Rx extremely useful. Rx is still messing with my head though and I suspect it will for some time to come.

As I am working through some of my existing ViewModel classes to convert them to ReactiveUI I also try and see if I can find better ways to do certain things.  One of the scenarios I have is that I have a list of accounts which is displayed on the screen.  The user can then select certain of the accounts which I will keep track of in a separate list of selected accounts.

public ObservableCollection<AccountViewModel> Accounts
{
    get { return accounts; }
}

public ObservableCollection<AccountViewModel> SelectedAccounts
{
    get { return selectedAccounts; }
}

The user is also allowed to do maintenance on the list of accounts which means that items can be added to or removed from the list of accounts.  Of course if an item gets removed from the list of accounts it must also be removed from the list of selected accounts otherwise it will not be valid anymore.  For his purpose I wrote the following piece of code to do some basic synchronisation between the two collections:

Accounts.CollectionChanged += (sender, args) =>
{
    if (args.Action == NotifyCollectionChangedAction.Remove)
    {
        foreach (AccountViewModel accountViewModel in args.OldItems)
        {
            SelectedAccounts.Remove(accountViewModel);
        }
    }
    else if (args.Action == NotifyCollectionChangedAction.Reset)
        SelectedAccounts.Clear();
};

With ReactiveUI I first of all changed the collections from ObservableCollection<T> to ReactiveCollection<T>:

public ReactiveCollection<AccountViewModel> Accounts
{
    get { return accounts; }
}

public ReactiveCollection<AccountViewModel> SelectedAccounts
{
    get { return selectedAccounts; }
}

And changed the collection synchronisation code the use the observable pattern:

Accounts.ItemsRemoved.Subscribe(x => SelectedAccounts.Remove(x));
Accounts.CollectionCountChanged.Subscribe(x =>
{
    if (x == 0)
        SelectedAccounts.Clear();
});

Unit tests pass and all still works as expected.  And I am one step closer to making more sense of Reactive Extensions

Google+ Signin for ASP.NET MVC

With ASP.NET MVC 4 Microsoft has added the ability to allow your users to log in to your application using various OAuth and OpenID providers.  Microsoft has supplied clients for Facebook, Twitter, Google, Microsoft, LinkedIn and Yahoo.  The Google client is based on OpenID and not OAuth.  With the recent announcement of Google+ Signin I set out to create a client which uses the Google+ login via OAuth instead of the standard OpenID login.

Google has supplied some great documentation on how to achieve this, but what I wanted to do was to create something which integrated nicely with the existing OAuth infrastructure which Microsoft supplied in MVC 4.

Overview of the Google OAuth Client

The Google OAuth signin process is described in detail in the Google Developers documentation.  This is pretty much the standard process for any OAuth 2.0 provider. There is one caveat however, and that is that Google expects the redirect URL to exactly match the one you define when your register your application in the Google API Console (I describe the application registration later in the blog post).  This creates a problem for us as the OAuth framework which Microsoft has supplied in MVC 4 appends extra parameters to the query string of the redirect URL.  One of these parameters is named “__provider__” and it is crucial for the MVC OAuth infrastructure to be able to know which provider to use.

After a lot of searching I came across a solution to this by Matt Johnson.  He has made his solution available on Github in the repository named https://github.com/mj1856/DotNetOpenAuth.GoogleOAuth2.  Actually a lot of our solution to the problem is pretty much similar and I unashamedly borrowed his solution to work around the extra parameters which are added to the redirect URL.

What Google allows you to do is to send extra data through to the Authentication server in a state parameter which gets round tripped and passed back to you by the response.  What Matt’s solution does is to strip the entire query string from the redirect URL which is generated by the OAuth Web Security classes and pass it on to Google in the state parameter.  Once Google responds back from the Authentication URL, the data from the state parameter gets re-injected into the request which is made from the Google Authentication back to our application.

Register the application on the Google API Console

The first step is to register your application in the Google API Console.  Once the application has been created, select the API Access tab and click on “Create an OAuth 2.0 client ID”.

Capture

In the next dialog specify the name of your application and click Next

Capture

The next part is to specify the callback URL, so to do this click the “more options” link in the dialog and specify the redirect URL.  It is important that the redirect URL points to the ExternalLoginCallback action of your Account controller:

Capture

Once done you can click on the “Create client ID” button.  Take note of the Client ID and Client secret as you will need these later on when registering the new Google+ signin client.

Capture

Putting it all together

Microsoft has supplied most of the infrastructure already in place, so to create our own Google OAuth client we simply inherit from the DotNetOpenAuth.AspNet.Clients.OAuth2Client class and implement the 3 abstract methods which are defined.

The first method we need to implement is GetServiceLoginUrl:

protected override Uri GetServiceLoginUrl(Uri returnUrl)
{
    UriBuilder uriBuilder = new UriBuilder(AuthorizationEndpoint);
    uriBuilder.AppendQueryArgument("client_id", this.clientId);
    uriBuilder.AppendQueryArgument("redirect_uri", returnUrl.GetLeftPart(UriPartial.Path));
    uriBuilder.AppendQueryArgument("response_type", "code");
    uriBuilder.AppendQueryArgument("scope", "https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email");
    uriBuilder.AppendQueryArgument("state", returnUrl.Query.Substring(1));

    return uriBuilder.Uri;
}

Note that we are stripping the redirect URL back to just the path and extracting the query string and passing that through in the state parameter.

Once the user has successfully authenticated against the Google servers a callback will be made to the redirect URL, which means it will go the the ExternalLoginCallback on our AccountController.  It is at this point which the request must be rewritten before it gets passed on to the OAuth Web Security classes.  The code which rewrites the request is implemented in the RewriteRequest() method of our GooglePlusClient class, so we need to add the call to this method before any of the other code gets executed.

[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
    // Rewrite request before it gets passed on to the OAuth Web Security classes
    GooglePlusClient.RewriteRequest();

    AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));

   // Rest of the controller follows as normal
}

At this point the OAuth classes will need to exchange the authorization code for an access token.  The source code for this is implemented in the second abstract method which we need to override, namely the QueryAccessToken(..) method.  This method calls back to the Google token endpoint and passes the authorization code as parameter. (For full documentation on this you can refer to the “Handling the Response” section in the Google documentation.)  The token endpoint will pass back a JSON object containing the access token, so we extract that from the response and pass it back to the OAuth Web Security infrastructure.

The third and final method we need to implement is the GetUserData() method.  This is called by the VerifyAuthentication() method of the base OAuth2Client class to retrieve a dictionary containing the user information.  The only key that is required to be present in the dictionary is the “id” key, which is the ID of the user on Google.  It is also looking for key named “username” or “name”, although this is not required.  Google does not return a username field so we create a username field in the dictionary with the value of the email address.

The final bit is to register our new GooglePlusClient class in the AuthConfig class:

public static class AuthConfig
{
    public static void RegisterAuth()
    {
        OAuthWebSecurity.RegisterClient(new GooglePlusClient("YOUR CLIENT ID", "YOUR CLIENT SECRET"), "Google+", null);
    }
}

Run the application and select to log in with Google+.  You will be selected with the new Google+ signin screen.

Capture

As always, all source code can be found in Github in the repository https://github.com/jerriep/GooglePlusOAuthLogin/

Split Views and ViewModels in Caliburn Micro

As mentioned in my previous blog post I am developing a Windows Store application using Caliburn Micro (CM) in which I have the views and view models split into different assemblies.  CM is largely convention based and therefore expect things is certain places.  One of these conventions is the way in which CM locates views and view models.  Let’s say that we have an application with a root namespace of MyApplication and our views are located in the namespace MyApplication.Views.  The CM convention is that it will expect the view models to be located in the same assembly in the namespace MyApplication.ViewModels.  Working outside of this convention will cause CM to be unable to find the view models for your view and vice versa.

Luckily for us CM allows us to override these default conventions with our own and tell the framework where to locate our views and view models.  For the purposes of this blog post I have created an application which consists of two assemblies.  The first is called Client and is a Windows Store application which contains among other things my views in the namespace Client.Views.  The second is a Class Library called Common and contains my view models in the namespace Common.ViewModels.

Untitled

Informing Caliburn Micro where to locate our views and view models in this case consists of  two parts.  The first part is to tell it what the namespaces are for the views and view models, and the second part is to tell it in which assemblies the views and view models can be located.

For the first part we will need to configure the type mappings for the ViewLocator and ViewModelLocator.  This is done in the Configure method of our App class:

var config = new TypeMappingConfiguration
{
    DefaultSubNamespaceForViews = "Client.Views",
    DefaultSubNamespaceForViewModels = "Common.ViewModels"
};
ViewLocator.ConfigureTypeMappings(config);
ViewModelLocator.ConfigureTypeMappings(config);

In the code above we create a new instance of the TypeMappingConfiguration class and override the values of the DefaultSubNamespaceForViews and DefaultSubNamespaceForViewModels properties.  The default values for these two properties are “Views” and “ViewModels” respectively.  Note that as the name of the properties suggest we only need to specify the sub-namespaces, or rather the parts of the namespaces which differ.  If we for example had our views in a namespace called “MyApp.Views” and our view models in a namespace called “MyApp.Logic.ViewModels”, because they both have the part of the namespace called “MyApp” in common we would only need to specify the parts which differ:

var config = new TypeMappingConfiguration
{
    DefaultSubNamespaceForViews = "Views",
    DefaultSubNamespaceForViewModels = "Logic.ViewModels"
};
ViewLocator.ConfigureTypeMappings(config);
ViewModelLocator.ConfigureTypeMappings(config);

In our example however there are no common parts to the namespaces so we specify the complete namespaces.

The second part we need to configure is to tell Caliburn Micro in which assemblies to locate the views and view models.  By default it will look in the same assembly where the App class is located, in this case the assembly called Client.  To tell it to look at additional assemblies we simply override the SelectAssemblies() method of our App class to add the assembly which contains our view models to the list of assemblies:

protected override IEnumerable<Assembly> SelectAssemblies()
{
    var assemblies = base.SelectAssemblies().ToList();
    assemblies.Add(typeof(MainViewModel).GetTypeInfo().Assembly);

    return assemblies;
}

With that very basic and simple configuration done we can now develop our application and keep our views and view models in separate assemblies.

As always the full code for this blog post can be found on Github at https://github.com/jerriep/CaliburnMicroSplitViewAndViewModel/

 

Caliburn Micro: Beware the default Windows Store app templates

I was recently dumbfounded by an apparent issue with Caliburn Micro in a Windows Store application being unable to locate the view model for a view.  The symptoms was that the application navigated correctly to my view, but the data from the view model was not being displayed on the page.

What complicated matters a bit more was that my views and view models were located in different assemblies and non-default namespaces, therefore I immediately suspected the problem was located there.  After some debugging I determined that Caliburn Micro was indeed locating and instantiating the correct view model for my view, but somehow the view model was not bound to the view.

My application was using the view first approach, so on application launch the following code was executed.

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    DisplayRootView<MainView>();
}

I decided to switch it around to the view model first approach by changing my OnLaunched() method and all of a sudden it worked.

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    DisplayRootViewFor<MainViewModel>();
}

I knew that was not a proper solution and did some more digging.  The culprit turned out to be the fact that the templates for Windows Store applications in Visual Studio sets the DataContext of a page to the DefaultViewModel property of the LayoutAwarePage class and somehow CM does not set the DataContext of a page if it has already been set.

Untitled

The solution turned out to be as simple as deleting the offending line of markup and after that Caliburn Micro was setting the DataContext correctly and the data was displayed on the page.

There is a discussion on the Caliburn Micro website which describes this issue and the reason behind it.

Passing custom parameters to Caliburn Micro actions

I have been working with Caliburn Micro (CM) for the past month, using it in a new Windows 8 application I am busy developing.  CM is largely convention based but it does allow you to override and customize a lot of those conventions as well as provide other points of extensibility.

The initial solution

I recently had a scenario where I had a ListView displaying the a list of items.  When a used clicked on one of the items in the ListView, a method on the underlying ViewModel was called using the CM Action mechanism.  I needed to access the model for the item which was clicked on as I needed to perform some actions on that.  Looking at the CM documentation on Actions you will notice that there are a number of arguments which you can pass to the method which is executed, of of which being $eventArgs. For the click event on a ListView this will be of type ItemClickEventArgs.  From there it is as simple as inspecting the ClickedItem property of the event arguments as that will contain my underlying ViewModel item.

public void TakeActionOnEventArgs(ItemClickEventArgs args)
{
    AccountViewModel account = args.ClickedItem as AccountViewModel;

    if (account != null)
    {
        var dialog = new MessageDialog(string.Format("You clicked {0}", account.Name), "Using $eventArgs");
        dialog.ShowAsync();
    }
}

And to hook the method up to my view I declare the XAML for the ListView as follows:

<ListView
    x:Name="accountsListView1"
    AutomationProperties.AutomationId="AccountsListView1"
    AutomationProperties.Name="Accounts1"
    TabIndex="1"
    Margin="0,10,0,0"
    Padding="10,0,0,60"
    ItemsSource="{Binding Accounts}"
    ItemTemplate="{StaticResource Standard80ItemTemplate}"
    SelectionMode="None"
    IsItemClickEnabled="True"
    caliburn:Message.Attach="[Event ItemClick] = [TakeActionOnEventArgs($eventArgs)]"
    IsSwipeEnabled="false" />

Notice in the XAML above that I use the Message.Attach syntax, which will then be parsed by CM and will execute the TakeActionOnEventArgs() method passing along the event  arguments to the method.  Also notice for my purposes I needed to set the IsItemClickEnabled property to true, as it is set to false by default.

A platform independent solution

Normally the solution above will suffice, but for my particular application I could not allow platform specific code to bleed into my view models, as the application will eventually need to run on multiple platforms (Windows Store apps, Windows Phone, etc).

Reading further through the CM documentation I noticed that the $eventArgs is simply a “special value” which is understood by the parser and that CM allow us to specify our own special values using the SpecialValues collection of the MessageBinder class.  In the Configure() method of my Application I specified the following code to define my own special value called $account.

MessageBinder.SpecialValues.Add("$account", context =>
{
    if (context == null || context.EventArgs == null)
        return null;

    return
        ((ItemClickEventArgs)context.EventArgs).ClickedItem as AccountViewModel;
});

The method in my ViewModel is also changed to take an AccountViewModel as parameter.

public void TakeActionOnAccount(AccountViewModel account)
{
    if (account != null)
    {
        var dialog = new MessageDialog(string.Format("You clicked {0}", account.Name), "Using $account");
        dialog.ShowAsync();
    }
}

And finally the markup in my XAML is also changed to bind the $account parameter to the Action Message.

<ListView
    x:Name="accountsListView2"
    AutomationProperties.AutomationId="AccountsListView2"
    AutomationProperties.Name="Account21"
    TabIndex="1"
    Margin="0,10,0,0"
    Padding="10,0,0,60"
    ItemsSource="{Binding Accounts}"
    ItemTemplate="{StaticResource Standard80ItemTemplate}"
    SelectionMode="None"
    IsItemClickEnabled="True"
    caliburn:Message.Attach="[Event ItemClick] = [TakeActionOnAccount($account)]"
    IsSwipeEnabled="false" />

Please note that the scenario above is very simplistic for demonstration purposes and may not make sense as everything is located in one assembly.  In my proper application however the view models is located in a completely separate assembly which is not platform specific and can then be reused by all the platform specific assemblies by simply linking the one shared file into the platform specific assemblies.  This is similar to what is described in an article in the Xamarin Developer Centre.  The code which defines the $account special value is located in the platform specific assembly and will differ between the various platforms.

All code for this article is located in a Github repository at https://github.com/jerriep/CaliburnMicroActionParameters.

Customizing External Login Buttons in ASP.NET MVC 4

With the introduction of ASP.NET MVC 4 Microsoft has added functionality to allow you to easily add the ability for your users to log in to your websites using the existing their Facebook, Twitter, Google and other accounts using OAuth.  The standard functionality which is included in the default ASP.NET MVC 4 templates is pretty bland and does not apply any of the branding of the OAuth services you are using.  In this blog entry I will demonstrate how to easily add the appropriate branding to the login buttons for the various OAuth services.

To get more details on exactly how to enable OAuth authentication in your website please read the blog entry entitled OAuth/OpenID Support for WebForms, MVC and WebPages first.

Register OAuth providers

We start of by creating a new ASP.NET MVC 4 Internet Application and enabling the various OAuth providers we would like to use in the App_Start\AuthConfig.cs

OAuthWebSecurity.RegisterTwitterClient(
    consumerKey: "x",
    consumerSecret: "x");

OAuthWebSecurity.RegisterFacebookClient(
    appId: "x",
    appSecret: "x");

OAuthWebSecurity.RegisterGoogleClient();

OAuthWebSecurity.RegisterLinkedInClient(
    consumerKey: "x",
    consumerSecret: "x");

OAuthWebSecurity.RegisterYahooClient();

Add Social Buttons CSS

The next step is to get a set of good looking social login buttons.  I decided to use the Zocial CSS social buttons which you can grab directly from the Github repository available at https://github.com/gustavohenke/zocial-less. Add them to the project by copying the CSS file and the font files into the Content folder of your project and add the CSS file to your App_Code\BundleConfig.css file

bundles.Add(new StyleBundle("~/Content/css").Include(
    "~/Content/site.css",
    "~/Content/zocial.css"));

To use the Zocial CSS social buttons you can use any HTML such as a, div, span, button etc. and add a CSS class of “zocial” as well as the class for the service that you want to style the button for.  For example the HTML code

<a href="#" 
    class="zocial facebook">
    Sign in with Facebook
</a>

will render the button

image

Customizing ASP.NET MVC Output

The final step required is to customize the output of the partial views which was created by the ASP.NET MVC Internet project template.  There are two views which we need to edit and both can be found under Views\Account.

The first one is _ExternalLoginsListPartial.cshtml and is used to display the list of available logins on the Login page as well as the Account Management page.  We alter this view by rendering the correct CSS class which will allow Zocial to render the button correctly.  We are lucky in that the provider names in ASP.NET MVC corresponds to the correct CSS classes in Zocial, but remember that CSS is case sensitive, so we force the provider name to lower case using AuthenticationClient.ProviderName.ToLower():

<button 
    type="submit" 
    name="provider" 
    value="@p.AuthenticationClient.ProviderName" 
    class="zocial @p.AuthenticationClient.ProviderName.ToLower()" 
    title="Log in using your @p.DisplayName account">
    @p.DisplayName
</button>

The second view is _RemoveExternalLoginsPartial.cshtml which displays the existing services linked to a user’s account.  Here we also need to render the correct CSS class for Zocial to do its magic.  This view simply renders the name if the service inside a TD, so we surround it with as SPAN with the correct class attribute:

<span class="zocial @externalLogin.ProviderDisplayName.ToLower()">
    @externalLogin.ProviderDisplayName
</span>

The final result of the Manage Account page with the correct styling applied can be view below:

The source code for this blog post can be found on Github at https://github.com/jerriep/CustomizeOAuthLoginBranding

Move Git repository from Github to TFS

Microsoft recently made Git source control available as an alternative source control provider on Team Foundation Service. I decided to move my existing private repositories from Github to TFS. This video describes the process.