Changing the ordering for single bundles in Asp.Net 4

The new bundling support for Asp.Net MVC and WebForms is superb, and as it’s all built into the new framework, there’s no real reason not to use it if you’re not doing anything of this kind already. In a nutshell, it allows you to package up all your related scripts and css files and serve them us as one request, and even minify them in the process. You can even get it to transform LESS files and all sorts of other cool stuff.

And that’s what I like about it; it’s so configurable, and it even does some smart things for you, like automatically favouring minified javascript files over non-minified (based on popular filename convention) when running with optimizations turned on. It will even put known framework javascript files first in the bundle automatically, such as jQuery or Prototype scripts, to make sure they run before your own code which uses their types gets executed.

But this last one can be stick, like in the case I had today. I was using the popular Plupload javascript file uploader, which requires a number of Javascript files to be included on the page. It also has a jQuery-UI extension library, which must be executed after the primary Plupload library, otherwise it complains about missing types and methods. So I created a bundle to handle all this stuff, which looks like this:

string pluploadBase = "/scripts/jquery/plupload/1.5.4/";
var pluploadBundle = new ScriptBundle("~/bundles/js/plupload").Include(
    pluploadBase + "plupload.full.js",
    pluploadBase + "plupload.browserplus.js",
    pluploadBase + "plupload.flash.js",
    pluploadBase + "plupload.gears.js",
    pluploadBase + "plupload.html4.js",
    pluploadBase + "plupload.html5.js",
    pluploadBase + "plupload.silverlight.js",
    pluploadBase + "jquery.ui.plupload/jquery.ui.plupload.js");
bundles.Add(pluploadBundle);

This looks fine, except what will actually happen is the jQuery-UI library will be rendered first when the bundle is actually used on the page. This is how the bundle is written out without optimisations turned on, when the bundle is configured exactly as above:

Luckily, in this case I want to just write out the scripts as they appear in my bundle without Asp.Net doing anything fancy to it. I can write a custom BundleOrderer by implementing the IBundleOrderer interface:

class PassthruBundleOrderer : IBundleOrderer
{
    public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
    {
        return files;
    }
}

Simple: it just returns the same file list back to the caller without doing any ordering on it whatsoever. We can now apply this orderer to this one specific bundle that needs it, by setting the Orderer property, and our code becomes:

string pluploadBase = "/scripts/jquery/plupload/1.5.4/";
var pluploadBundle = new ScriptBundle("~/bundles/js/plupload").Include(
    pluploadBase + "plupload.full.js",
    pluploadBase + "plupload.browserplus.js",
    pluploadBase + "plupload.flash.js",
    pluploadBase + "plupload.gears.js",
    pluploadBase + "plupload.html4.js",
    pluploadBase + "plupload.html5.js",
    pluploadBase + "plupload.silverlight.js",
    pluploadBase + "jquery.ui.plupload/jquery.ui.plupload.js");
pluploadBundle.Orderer = new PassthruBundleOrderer();
bundles.Add(pluploadBundle);

And the order is now correct in the browser:

You can of course apply any ordering you like here, but at least it’s one way to break convention for one specific instance, should you need it!

Snippets , , , , , , ,

Real-time system resource monitor with SignalR, WCF and KnockoutJS

Application building time! This article is designed to give you, the reader, some grounding in a few different technologies and help you build a working application which may or may not be actually useful. Nonetheless, it should be fun to build and at the end you will hopefully see some nice web wizardry to keep you entertained. Beware – this is a lengthy one.

Here’s what we will build:

  • An MVC web application, exposing a WCF service across SSL
  • A console application to securely send processor and memory information to the service
  • A web page to show these system stats in real time using SignalR and KnockoutJS
These are the technologies we are going to use:

And this is what will happen. The console application will run on the host PC and post system resource usage across a secure HTTPS channel to the WCF service which is running on the website. The service will then send this information straight to the SignalR hub, which will then broadcast the information to all clients, who will display this information on the page.

In this article, I am using Visual Studio 2012 RC with Asp.Net MVC 4 installed.

Before we get started, you should familiarise yourself just a little with SignalR and KnockoutJS as I’m not going to go into the technical concepts behind them, but merely show you how to use them. Both sites have excellent tutorials here and here to get you started. Also, I assume you know your way around Asp.Net MVC.

You can also download the tutorial project and follow along with the finished demo if you like. Note that I have enabled Nuget Package Restore to keep the file size down, so if you do download it, open up your package manager and restore the missing packages first!

Read more »

Articles , , , , , , ,

Basic Authentication with Asp.Net WebAPI

On a recent project, I undertook the task of implementing a RESTful API using the new Asp.Net WebAPI framework. The aim was to support clients of all types, including a .Net desktop app and iOS and Android mobile apps. My API had to support some sort of authentication mechanism.

Since this was a basic application (to be used as a learning tool for the other developers on our team) we decided to use Basic HTTP Authentication. As the name suggests, it’s a simple protocol whereby the client sends an authorization token as a header in the HTTP request, and the server decodes that token to decide whether or not it is valid. If it is, the request continues, otherwise it (should) return a 401 Unauthorized response.

So how can we implement this with WebAPI? With an Action Filter, of course.

The Basic Authentication Action Filter

Start by creating a new class for your filter. This must inherit from System.Web.Http.Filters.ActionFilterAttribute, which is different from the normal namespace that are used for Asp.Net MVC Action Filters. This one lives in System.Net.Http.Filters. Be careful to subclass the correct type and don’t get confused. Also, override the OnActionExecuting method:

public class BasicAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
	public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
	{
	}
}

We will use this method to intercept the API and check that everything is OK with the security side of things (well, as OK as Basic Auth can be!). First, lets check we have an authorization header:

if (actionContext.Request.Headers.Authorization == null)
{
	actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}

Simple stuff here. The fact that this action filter is executing implies that we want to protect the action that it attributes, and so if we don’t have a header, we’re not authorized.

If we have a header, lets parse the value:

else
{
	string authToken = actionContext.Request.Headers.Authorization.Parameter;
	string decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authToken));

	string username = decodedToken.Substring(0, decodedToken.IndexOf(":"));
	string password = decodedToken.Substring(decodedToken.IndexOf(":") + 1);
        ...
}

Just grab the header value, decode it from Base64 back to a string, and then split it. The value that is encoded would normally:, but really if this is a custom solution you can make it anything you want if you’re in control of how the value is encoded and decoded (which here I am – I just decided to follow the standard).

Now that we have the username and password, it really is up to you as to how you use it. The normal thing would be to look up some database value and check if the user exists. In my case, I grab a couple of services to find the user that the credentials refer to, and I set the user into the current principal. I then defer execution to the base filter and allow the action to run:

IPasswordTransform transform = DependencyResolver.Current.GetService<IPasswordTransform>();
IRepository<User> userRepository = DependencyResolver.Current.GetService<IRepository<User>>();

User user = userRepository.All(u => u.Username == username && u.PasswordHash == transform.Transform(password)).SingleOrDefault();

if (user != null)
{
	HttpContext.Current.User = new GenericPrincipal(new ApiIdentity(user), new string[] { });

	base.OnActionExecuting(actionContext);
}

If the user wasn’t found, simply return a 401:

else
{
	actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}

In the code above where I set HttpContext.Current.User, I am just using a custom type called ApiIdentity, which is an implementation of IIdentity and allows me to store a user entity against the username. For brevity, it’s implementation is:

using System.Security.Principal;

public class ApiIdentity : IIdentity
{
	public User User { get; private set; }

	public ApiIdentity(User user)
	{
		if (user == null)
			throw new ArgumentNullException("user");

		this.User = user;
	}

	public string Name
	{
		get { return this.User.Username; }
	}

	public string AuthenticationType
	{
		get { return "Basic"; }
	}

	public bool IsAuthenticated
	{
		get { return true; }
	}
}

Using the Basic Authentication action filter

To use this thing, just decorate any action or controller with [BasicAuthentication], and any requests to those actions will require that the Authorization header is sent:

// GET /api/accounts
[BasicAuthentication]
public IEnumerable<OwnerAccountDto> Get()
{
	var accounts = _accountsRepository.All(a => a.OwnerKey == AuthorizedUser.Guid).ToList();

	return Mapper.Map<IEnumerable<OwnerAccountDto>>(accounts);
}

I went one step further than this and created an AuthorizedApiController which already has this attribute on it. Furthermore, I added an accessor to get the actual user entity that was authorized when the request was made:

[BasicAuthentication]
public class AuthorizedApiController : ApiController
{
public User AuthorizedUser { get { return ((ApiIdentity)HttpContext.Current.User.Identity).User; } }
}

A quick note on unit testing: having this property return something straight out of the current HttpContext instance mucks things up a little for unit testing, since there won’t be a context to look at in that scenario. The way to combat it is to either:

  • Create a provider model to retrieve the authenticated user through some IAuthenticatedUserProvider interface
  • Use a framework such as Moq to allow you to mock up a context just for this scenario (available through Nuget too)

Now you have the tools to custom-build an authentication scheme for your Web Api. Happy.. authenticating!

Articles , , , , ,

Fun with action filters

I was fortunate enough to be able to attend the brilliant DevWeek developer’s conference in London this year, and even more lucky to attend a lecture by Dino Esposito (please check out his brilliant Architecting Applications for the Enterprise book) on Asp.Net Action Filters. The purpose of his session was to demonstrate the importance of Action Filters and how we should all be using them much more than we normally do. I will be the first to admin that action filters are not the first possible solution that comes to mind when trying to solve a particular architectural problem in my Asp.Net MVC application.

I must say though, I was inspired. Yes, I realise I had previously posted about one particular useful action filter, but I really haven’t done too much with them until now. Dino put forth some uses for them, which I believe are discussed in more detail in his MVC book:

  • Using an action filter to figure out which button was pressed (on a multi-button form) and compartmentalise the resulting code path
  • An action filter which automatically populates generic data on a view model (imagine a list of countries or some other static data required by your view)

We’ve all had some grief with the first scenario at some stage or another. It’s just not quite as easy to do as one would expect. The second allows you to abstract away some data population code and generally keep things a bit tidier than they otherwise would.

Today I created another action filter which takes a CSV list of data, parses it, and gives you a strongly-typed list of values. It looks like this:

[SplitString(Parameter="contentItemKeys", Delimiter=",")]
public virtual ActionResult GetItemInfo(IEnumerable<Guid> contentItemKeys)
{
}

So imagine that I have POSTed a comma-delimited list of GUIDs to this action. Normally, if there is one GUID then Asp.Net MVC should be able to resolve that properly and give you a list with one thing in it. However, if you have more than one GUID in that comma-delimited list, then you will have an empty list given to you. Why? Because the framework doesn’t know how to parse that list properly.

You could use a custom model binder to achieve the desired effect, but creating an action filter to do the same thing is much neater and much more flexible.

I’ve created an action filter called ‘SplitString’ and it works like this:

  • The filter accepts a couple of arguments: the parameter you want to act on, and the delimiter to use.
  • It overrides the OnActionExecuting method and looks for the specified parameter, first in the routing data, then in request data.
  • It then finds the type that each item should be, using a little reflection.
  • It then parses the list, converts each item in the parsed string to the desired type, and spits out the full list.

First, the class definition:

[AttributeUsage(AttributeTargets.Method)]
public class SplitStringAttribute : ActionFilterAttribute
{
    public string Parameter { get; set; }
    public string Delimiter { get; set; }

    public SplitStringAttribute()
    {
        Delimiter = ",";
    }

Inside OnActionExecuting, lets find the value we need to work with:

string value = null;
HttpRequestBase request = filterContext.RequestContext.HttpContext.Request;

if (filterContext.RouteData.Values.ContainsKey(this.Parameter)
	&& filterContext.RouteData.Values[this.Parameter] is string)
{
	value = (string)filterContext.RouteData.Values[this.Parameter];
}
else if (request[this.Parameter] is string)
{
	value = request[this.Parameter] as string;
}

Next we need to find the type to convert to. Specifically, we need to find the type of the generic argument which forms the type of the parameter we’re interested in. So if our parameter is IEnumerable<T>, I want to know what type T is. I’ve wrapped this up in a method:

Type listArgType = GetParameterEnumerableType(filterContext);

 

private Type GetParameterEnumerableType(ActionExecutingContext filterContext)
{
	var param = filterContext.ActionParameters[this.Parameter];
	Type paramType = param.GetType();
	Type interfaceType = paramType.GetInterface(typeof(IEnumerable<>).FullName);
	Type listArgType = null;

	if (interfaceType != null)
	{
		var genericParams = interfaceType.GetGenericArguments();
		if (genericParams.Length == 1)
		{
			listArgType = genericParams[0];
		}
	}

	return listArgType;
}

Here we simply:

  • Find the type of the parameter using the filterContext
  • Check to see if the type is IEnumerable<>. We do this simply by getting the interface and checking if it is not null
  • Finally we get any generic arguments, check that there is exactly one, and then return that type. This is the type that we will convert each item in our CSV list to.

Next, we process our CSV string and create our container list:

string[] values = value.Split(Delimiter.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

Type listType = typeof(List<>).MakeGenericType(listArgType);
dynamic list = Activator.CreateInstance(listType);

We just split the string according to the delimiter that we need to use, then create a new generic list with the type we procured earlier. I’ve used a dynamic type here to make it much easier and more efficient to work with.

Next, we run through each value in our CSV list and add it to this new generic list:

foreach (var item in values)
{
	try
	{
		dynamic convertedValue = TypeDescriptor.GetConverter(listArgType).ConvertFromInvariantString(item);
		list.Add(convertedValue);
	}
	catch (Exception ex)
	{
		throw new ApplicationException(string.Format("Could not convert split string value to '{0}'", listArgType.FullName), ex);
	}
}

The real magic here is the type converter. We can simply pass it a type and an item to convert and it will just do it for you, in a nice generic way. This means you don’t have to manually support a known list of types – let the framework handle that for you!

Finally, and the real cherry on top, is that to make all this work, we simply substitute the original action parameter value with this new list that we’ve just created:

filterContext.ActionParameters[this.Parameter] = list;

The result is, your action parameter will now be populated correct with the parsed list of values, in a strongly typed fashion.

Download the full code file if you wish to inspect it further, or to use as you like.

Articles , ,

Asp.Net Bundling, minification and convention

The new “bundling” support in Asp.Net MVC 4 looks massively appealing to .Net web developers – finally, an integrated way to dynamically package up multiple Javascript/CSS files into one request, and minify them on your behalf. Not only that, the results can be cached and reused until the files change. What’s not to like?

Today me and @evadi discovered another little sparkle to this already very useful feature. I’ll highlight this specially to try and get across its importance:

The bundling framework (by default) will automatically favour JS files which end in .min.js.

This means that, when you enable default bundling in global.asax:

BundleTable.Bundles.EnableDefaultBundles();

Then you put some scripts in a folder:

And then you reference the bundle (as-per the new syntax) from your page:

<script src="@System.Web.Optimization.
BundleTable.Bundles.ResolveBundleUrl("~/MyScripts/js")"></script>

Only script.min.js is actually returned in the request; script.js is completely ignored. I tried changing the filename of the former to script-min.js and I found that both scripts were being included in the returned script, so there is definitely some logic going on to try to make use of existing minified scripts if they are available, provided they follow this convention.

Not only that, but files with a debug.js extension are completely ignored.

Controlling this behaviour

To begin with, you can turn this behaviour off by setting the EnableFileExtensionReplacements property on Bundle to false:

Bundle bundle = new Bundle("~/myscripts/js", new JsMinify());
bundle.EnableFileExtensionReplacements = false;

After doing this, all the scripts in the specified folder which match the file mask will be loaded. This flag does not seem to affect files with a debug.js extension, they are still ignored.

You can also have influence over which extensions get treated as “special”. For example’s sake, say your convention is to have all minified Javascript files have the extension of .minified.js, then you can register this extension by adding it to the FileExtensionReplacementList collection on the Bundle table:

BundleTable.Bundles.FileExtensionReplacementList.Add("minified");

It gets a bit sticky now because this opens up the possibility of including multiple minified files, especially if you have a mix of conventions in one directory. So what else can you do?

Build a custom bundle type

You can also create a new Bundle type which inherits from System.Web.Optimization.Bundle and alter the behaviour there. Luckily, a method named EnumerateFiles can be overridden, and a new implementation supplied. As another example, imagine that I wanted to filter out anything that contained the word ‘min’ in order to make sure that my Javascript files were processed by a funky custom minifier that I had just written, and I didn’t want to use files that had already been minified by some other process:

// CustomBundle.cs
public class CustomBundle : Bundle
{
  public CustomBundle(string vpath, IBundleTransform transform)
    : base(vpath, transform)
  {
  }

  public override IEnumerable<System.IO.FileInfo> EnumerateFiles(BundleContext context)
  {
    var files = base.EnumerateFiles(context);

    // select only non-minified files (according to naming convention)
    files = files.Where(c => c.Name.Contains("min") == false).ToList();

    return files;
  }
}

// global.asax.cs
Bundle bundle = new CustomBundle("~/myscripts/js", new JsMinify());
bundle.AddDirectory("~/myscripts", "*.js");
BundleTable.Bundles.Add(bundle);

Unfortunately even at this stage any files which end with debug.js are filtered out for us – so far I haven’t found a way to extend the framework to prevent this behaviour. I’m keeping in mind that this isn’t a final release, and that some work may be done in this area before the final version appears.

In conclusion, this certainly eases my mind when throwing the default bundler at a folder which contains a mix of minified and unminified libraries, knowing that – provided the filenames follow convention – it will pick out the correct one and minify it if necessary. Also, if needed I can provide implementations which can select the files I want to bundle up without having to manually add each individual file manually; for a large project, this can easily become unwieldy.

Articles , , , ,

ScriptSharp: Taking care of ‘this’

Making sure ‘this’ points to exactly what you think it does in Javascript is one of the challenges that a new programmer to the language has to overcome. Script# makes this somewhat easy for us because it tries to make sure it points to exactly what we’d expect it to if we were writing a normal C# app.

Take this snippet, for example:

jQueryObject buttons = jQuery.Select(".homepageCreateButton");

buttons.MouseOver(delegate(jQueryEvent e)
{
	jQueryObject button = jQuery.This;
});

Here I’m selecting some buttons and applying a click handler. The generated code here is as you would expect, where jQuery. This clearly translates to $(this):

var buttons = $('.homepageCreateButton');

buttons.mouseover(function(e) {
    var button = $(this);
});

What happens though when I start using the C# keyword ‘this’ in my delegate?

jQueryObject buttons = jQuery.Select(".homepageCreateButton");

buttons.MouseOver(delegate(jQueryEvent e)
{
	jQueryObject button = jQuery.This;

	object a = this;
});

This gets compiled to:

var buttons = $('.homepageCreateButton');
buttons.mouseover(ss.Delegate.create(this, function(e) {
    var button = $(this);
    var a = this;
}));

.. which is not quite the same thing. As soon as the Script# compiler has detected that I am making use of the ‘this’ pointer it wraps the delegate call in a method and changes the context of the code inside the delegate so that ‘this’ points to the current instance of the class. This is of course the exact behaviour we would expect and love in C#, and for the most part this is also a good thing in Javascript. By the way, this transformation also happens if you implicitly access a class-level member without using the ‘this’ keyword.

However, look at what it has done to our jQuery selector; we expected ‘this’ to be the current element that we are handling the ‘mouseover’ event for, but now that has changed and we are effectively selecting the current instance of the class through a jQuery selector, which of course is nonsense.

To get around this and make sure that you’re accessing the actual object that you want inside the delegate, you should make use of the CurrentTarget property on jQueryEvent:

jQueryObject button = jQuery.FromElement(e.CurrentTarget)

Just be careful when you intend to use ‘this’ and ‘jQuery.This’ together in a delegate, as they will not behave as you would expect in this case.

Articles , , , ,

.Net Image Processor v1.2 released!

I’ve just put another release out for .Net Image Processor, my image processing and resizing code library for .Net and GDI, which includes a number of new filters, including:

  • Greyscale
  • Sepia
  • Invert
  • Image watermark
  • Text watermark

The first three also introduce a small framework for applying any sort of single pixel-based filter (as opposed to kernal-based filters) where you can simply create an implementation of PixelFilter and supply your own algorithm for manipulating a single pixel (a blog post is forthcoming on this soon).

You can grab the latest version from the project homepage, or you can update the Nuget package from within Visual Studio. To see how to use all of the available filters, have a scan of the documentation.

So what’s coming next?

I’m looking into using a couple of third-party libraries for a couple of prominent issues:

Both of these issues will be looked at for the 1.3 release.

Projects , , , , ,

.Net Image Processing library now available

This is a pet project which I’ve had around for a while now, which started off as a simple wrapper for GDI+ which allows you to create thumbnails from images. It’s turning into something a bit more than that, with an extensible filter framework where filters can be chained together. Also supports image conversion to/from Jpeg, PNG, TIFF, Bmp and GIF.

The idea is that over time I will be developing more and more filters which can be plugged in, with support coming for batch processing and asynchronous processing. Finally, the entire project is all open-source and free!

All the documentation for how to use it is all contained within the project homepage (there is more technical documentation to come), so without further ado here are all the links you need:

Nuget Support

What’s more, the project is also hosted on Nuget – so if you run Visual Studio 2010 with the excellent Nuget extension you can just install the project from there. The package name is Simplicode.ImageProcessor.

I would love to hear any feedback or issues you have if you use the library – you can get in touch with me directly or post a review on the project site!

Projects , , , ,

Problems with ResourceManager and neutral culture in Asp.Net MVC

I’ve been struggling with this for a couple of hours now and found a solution that I would like to share.

The problem is this: I added a resource file to my project as an Embedded Resource, configured the namespace as “Resources.Dialog” and set its Custom Tool property to “PublicResXFileCodeGenerator”. I then added some string resources to the file.

After inspection of the generated code file, everything looks normal. Next, I need to be able to access my resources dynamically, rather than simply using my Dialog resource class directly.

You would be tempted to do something like this:

ResourceManager dialogResources = new ResourceManager(typeof(Resources.Dialog));
string myString = dialogResources.GetString("MyString");

This would work in theory, but instead (for me at least) it throws this nasty exception on the call to GetString():

MissingManifestResourceException: Could not find any resources appropriate for the specified culture or the neutral culture

I might be expecting this exception if I hadn’t provided a neutral culture resource file (which are basically your ‘fallback’ resources if you’re not using a supported culture), or if I had defined the resource file in a different assembly, but I’m not. This is a simple neutral culture resource file, in the same assembly as where the resource is being used from.

I don’t know why its doing this, but I do know what I changed to finally fix it.

The class which is generated by the resource file exposes a static ResourceManager instance which is set up to manage itself – so the solution is to use this rather than create your own!

Therefore, the above code becomes:

ResourceManager dialogResources = Resources.Dialog.ResourceManager;
string myString = dialogResources.GetString("MyString");

.. and the exception goes away.

Snippets , ,

Adding a new Jquery UI theme to the default Asp.Net MVC 3 Project

The default project template for Asp.Net is pretty functional out of the box, but an interesting feature is that new templates install jQuery and jQuery UI out of the box! In fact, jQuery UI now comes pre-installed as a Nuget package if you’ve got the latest MVC3 Tools Update (April 2011). If you’re following this while sitting at a MVC3 project already in development, you can simply install the latest jQuery UI repository release using Nuget from within Visual Studio, and you will get the same thing.

In case you did not know, you can start working with jQuery UI pretty quickly and easily by just including the style sheet and script in your layout page like so (your actual file names may vary slightly):

<link href="@Url.Content("~/Content/themes/base/jquery.ui.all.css")" type="text/css" rel="stylesheet" />
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>

This will get you working with a basic jQuery UI theme for all the components and controls which come with the framework. However, if you want to update the project with another jQuery theme to better suit your requirements, then you can do it like this.

First of all, find a theme using the jQuery UI theme roller that takes your fancy. For this example, I’ve chosen “Redmond” as it fits in nicely with the default Asp.Net MVC 3 theme, but you can chose any theme or construct your own. When you click download, it will ask you which components you want to download themes for – just leave it at the default, which is all of them – and click ‘Download’. After .zip archive has been downloaded, extract it to somewhere temporary, and explore its contents.

You will get a file structure which looks like this:

Everything you need is inside the “css” folder – if you open that now you will see a single folder which is named after the theme you just picked from the jQuery UI site. If you’ve created a custom theme, then it will be named “custom-theme” or something to that effect. You can also give it your own folder name if you change the options under ‘advanced theme options’ when you download the theme.

Right-click and copy this folder. Now, browse to the /content/themes folder of your MVC 3 application and paste the folder there. Now you should have two folders in that location – one called “base” and your new theme folder (see right).

All we need to do now is include this folder in your Visual Studio project. The easiest way to do this is to turn on “Show All Files” by clicking the little button at the top of the Solution Explorer tool window, then right-click on the theme folder (which will appear with a white folder icon) and select “Include in Project”.

Now, all that’s left is to include the theme’s style sheet into your layout, and you are done:

<link href="@Url.Content("~/Content/themes/redmond/jquery-ui-1.8.13.custom.css")" type="text/css" rel="stylesheet" />

Now your new theme will be automatically applied to any jQuery UI components you are using in your application. Here’s a shot of it working with jQuery UI Buttons:

You can apply the same process to any additional themes you want to install, just line up all your themes in the same folder and include the relevant style sheet on your pages.

Snippets , , , , , , ,