random .NET and web development musings

I wanted a simple way to manage canonical links in ASP.NET MVC.

It would have been nice to work these out automatically from the route tables, but for the project I am working on, its far too convoluted to be done easily, I’d rather maintain a fixed definition for each action.

Step up a custom `ActionFilterAttribute`:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class CanonicalUrl : ActionFilterAttribute
	readonly string url;

	public CanonicalUrl(string url)
		this.url = url;

	public override void OnResultExecuting(ResultExecutingContext filterContext)
		var uri = filterContext.RequestContext.HttpContext.Request.Url;
		var fullyQualifiedUrl = (uri.Scheme + "://" + uri.Host + this.url).ToLowerInvariant();

		foreach (var key in filterContext.RouteData.Values.Keys)
			fullyQualifiedUrl = fullyQualifiedUrl.Replace("{" + key.ToLowerInvariant() + "}",

		filterContext.Controller.ViewData["CanonicalUrl"] = fullyQualifiedUrl;
		filterContext.HttpContext.Response.Headers.Add("link", "<" + fullyQualifiedUrl + ">; rel=\"canonical\"");


You can then decorate your actions like this:

public ActionResult Show(string name)

Make sure you stick the link element in your page’s head:

<% if(ViewData["CanonicalUrl"] != null){ %>
	<link rel="canonical" href="<%: ViewData["CanonicalUrl"] %>" />
<%} %>

I’ve used two approaches to “embedding” the ascx views, one thats quite simple, and one thats a bit more complicated and needs quite a lot of explanation as to why I’m doing it that way.

The easiest way to do it is to embed the ascx file, and access it with a Custom VirtualPathProvider.

This approach however suffers several drawbacks.

The first problem comes at dev time. You have to rebuild every time you change the ascx. This might not be a problem for you, but in large projects it can add several seconds delay to every change you make, which for someone whos trying to be productive, can be very annoying.

The easiest solution to this is to modify the custom VirtualPathProvider above so that it is aware whether it is in dev or production mode. I do this with the debug attribute in the web config:

public bool AreInDevMode
		var section = ConfigurationManager.GetSection("system.web/compilation") as CompilationSection;
		return section.Debug;

Then, when you’re in dev mode, check the file system before checking for the embedded resource. This will perhaps involve some path hackery, but generally I’m ok with this because the path conventions in my projects are consistent.

The second problem with this method is that the view is essentially embedded as a string, the text that makes up the view ascx. This means the view has to be compiled at runtime. This has two issues:

a) its slow, especially when you have many views
b) you dont get build time compilation error checking.

So how do we solve this?

To compile the views, you need the ASP.NET Precompilation tool.

This will create a separate assembly for each compiled view. This is messy, so we can merge them together using the ASP.NET Merge tool.

Getting better, but you still have two assemblies, your main project code and the one with the views in. ILMerge to the rescue. However, before we do that I want to sort out the compiled view types.

If you open a precompiled view dll in reflector, you’ll find its rather messy and things aren’t named very nicely. For example, say your project has the following views:


You’ll end up with the following types:


So, what I wan’t to do is put them back into the correct namespace. Unfortunately, because certain characters that are allowed in file paths are not allowed in namespaces, these chars get converted to underscores and you therefore can’t work out the namespace you need from the compiled type name alone. (e.g. you dont know if “path_to_some_view_ascx” was originally “path/to/some/view.ascx” or “path/to-some.view.ascx“)

Therefore I iterate over the file system and look for any .ascx, .aspx and .master files, turn their paths into their corresponding type names. I then have a lookup table of the type name and its original path.

THEN I can use Mono.Cecil to alter the type names.

so for the file:


I calculate its type name:


and the name(space) I want it to have:


Do this for all the views and then I can ILMerge my two assemblies into one, nicely organised final package 😀

So how do you then get MVC to render the view?

First you need to extend WebFormsViewEngine, and override:

protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) {
    return new WebFormView(partialPath, null);

protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) {
    return new WebFormView(viewPath, masterPath);

So that it returns a custom View, which extends WebFormView and overrides Render:

public virtual void Render(ViewContext viewContext, TextWriter writer)

so that instead of creating the view using the BuildManager, it simply instantiates the type you worked out above.

If you followed any of that, well done!

In this series of posts I’m going to describe the techniques I use for supporting a plugin architecture in ASP.NET MVC.

What do I mean by plugin? Well, without going into the specific details of the system I’ve developed this for (it isnt important), a “plugin” is simply a bit of UI functionality I want to encapsulate into a package that I can reuse. These plugins typically include some codebehind, a view (ascx), some javascript and some css.

A typical plugin will look like this:


When using a plugin, I want to just drop a dll in the bin (or reference it, whatever). I don’t want to have to manually add a script tag for the js, or a link for the css, or put the ascx in some views folder. I want everything to be included in a single file, and for everything to just work ™.

To achieve this I use several techniques:

  • Embed the css and javascript into the assembly as resources
  • Precompile the view into the assembly
  • Use a custom virtual path provider to make debug easier, and find the files at runtime.

These posts won’t go in to exact detail about how everything works and is wired together in my system (again, it isnt important and would only obscure the details). This isn’t a tutorial on how to build a plugin framework (that may be a future series of posts), but hopefully it will give you a few tips and tricks to try things out yourself.
There’s lots of bits I’ll gloss over, like optimisation :)

In this post I’ll cover embedding the css and js.

Embedding JS and CSS

Set the Build Action of the files (css, js) to “Embedded Resource” to embed them.

To get the files out of the assembly as string, you’ll need some code that looks like this:

static string GetResource(string key)
    var stream = this.GetType().Assembly.GetManifestResourceStream(key);
    using (var streamReader = new StreamReader(stream))
        return streamReader.ReadToEnd();

One thing to note is the naming rules that apply when you embed a file. Namespace sections that begin with a number get the number prefixed with an underscores, slashes get converted to dots and dashes to underscores. For example:


You’ll probably want some function that looks like this:

static string GetKey(string name)
    // folders beginning with a number have an _ prepended.
    name = Regex.Replace(name, @"/([0-9])", "/_$1");
    // turn / to . and - to _
    return name.Replace('/', '.').Replace('-', '_');

OK so that’s how we can get the css and js data out of the assembly, but then what to do with it?

Well, you’re probably going to have multiple plugins on a page, so you will have multiple css and js to include and you’ll want to bunch all this together. If you have some underlying plugin awareness mechanism, you could just pull the files you need:

var scripts = new StringBuilder();
var styles = new StringBuilder();
foreach (var plugin in page.Plugins)
    var key = plugin.GetType().FullName;
    key = GetKey(key);
    scripts.Append(GetResource(key + ".js"));
    styles.Append(GetResource(key + ".css"));

OR you could just get all the files in some “namespace”:

var scripts = new StringBuilder();
var styles = new StringBuilder();
var names = this.GetType().Assembly.GetManifestResourceNames();
foreach (var name in names)
    else if(name.EndsWith(".css"))

And there you go, you can then render these two strings into your page in a script and style tag :)

Some other ideas / Variations

If you don’t want to render the css and js directly into the page, you could use a script tag with a src pointing at a fake file. The fake file could be mapped to an IHttpHandler in the Web.config, or use an MVC route to a controller action.

For example, route: /assets/scripts/plugins.js to some code that does something similar to the above.

Quick Link: Download the Example Code.

OK so here’s my problem,

My client wants most of the actions in their system to work slightly differently based on the authorization role of the logged in user. For example, Moderators can edit a user, but only some fields, Administrators can edit all fields for a user.

I don’t want to have different URIs for each action, I don’t want to have to faff about with routes, I want to do this transparently, with as little pain as possible.

One approach would be to have a switch inside the method (on the current users role) and delegate the action to the private method specific to that role. However this suffers several problems:

The main action method that gets called by the controller can only have a single Resource type, which means if you want different resource types per role, youre in a mess. You therefore have to accept FormCollection, then do binding and validation manually etc. etc. urgh. You also end up with 4 methods for each action. This quickly bloats your controller :(

So, what can we do about this? We’ll in this post I’ll show you how you can leverage the power of you IoC container to swap out the controller instance with one specific to the current user’s role.

Here’s what you do:

Create an IXXXController for each of your controllers you want to swap based on role, like this:

public interface IUserController : IController
	ActionResult Edit(int id);

Then, create your multiple implementations of this controller:

public class UserController_ForAdministrator : Controller, IUserController
	public override ActionResult Edit(int id)
		// this would really come from a repos
		var resource = new EditUser_AdministratorResource{ EmailAddress = "me@here.com"};

		return View("Edit_Administrator", resource);

	public ActionResult Edit(int id, EditUser_AdministratorResource resource)
		// do admin stuff here

		return RedirectToAction("Index");

public class UserController_ForModerator : HomeController
	public override ActionResult Edit(int id)
		// this would really come from a repos
		var resource = new EditUser_ModeratorResource{ EmailAddress = "me@here.com"};

		return View("Edit_Moderator", resource);

	public ActionResult Edit(int id, EditUser_ModeratorResource resource)
		// save moderator stuff here

		return RedirectToAction("Index");

Next, you need a custom IControllerFactory. Note in the example below I have forgone any error checking or optimisation for brevity, I have also omitted any Namespace checking.

public class CustomControllerFactory : IControllerFactory
	private readonly IEnumerable<Type> controllerTypes;

	public CustomControllerFactory()
		this.controllerTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => (t.IsInterface || !t.IsAbstract) && t.Name.EndsWith("Controller"));

	public IController CreateController(RequestContext requestContext, string controllerName)
		var currentUser = ObjectFactory.GetInstance<User>();

		var controllerInterface = this.controllerTypes.Where(t => t.IsInterface && t.Name.Equals("I" + controllerName + "Controller", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
		if (controllerInterface != null)
			return ObjectFactory.GetNamedInstance(controllerInterface, currentUser.Role) as IController;

		var controllerClass = this.controllerTypes.Where(
			t => t.IsClass && 
				t.GetInterfaces().Contains(typeof(IController)) && 
				t.Name.Equals(controllerName + "Controller", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();

		if(controllerClass != null)
			return ObjectFactory.GetInstance(controllerClass) as IController;

		return null;

Then simply wire things up in your Application_Start:

protected void Application_Start()
	ObjectFactory.Initialize(a =>


			// this is obviously a hack for the purposes of this post
			// here you would really be loading your real user
				.Use(c => new User { Role = "Moderator" });

	ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());

The controller wiring can easily be done by convention in StructureMap (and other containers) so you don’t have to list each one manually.

Download the Example Code here, aren’t I nice to you?

For those of you still running IIS6 who would like to have nice SEO friendly URLs, one option is to use ISAPI Rewrite.

First, add a “.mvc” handler mapping to the asp.net dll as per Phil Haacks post.

Obviously you’ll need ISAPI Rewrite installed, then you can create the following .htaccess file:

RewriteEngine on
AllowOverride All

# Ignore Assets folder
RewriteRule ^assets/(.*?)$ /assets/$1 [NC,L]

# Rewrite everything else to have .mvc on the end of the controller name
RewriteRule ^([^/]*)(/(?:.*?)*)?$ /$1.mvc$2 [NC,L]

I keep all my CSS, images and javascript under the /assets folder. If you have these elsewhere, you probably want to modify the first rewrite rule for your specific location.

N.B. you can probably ignore these folders in a much more elegant way, perhaps with a RewriteCond on the 2nd Rule. I’m not a master of this syntax yet so this will do for the time being, it works!

Some additional rules you may also want are the following:

# Rewrite favicon
RewriteRule ^favicon.ico(.*?)$ /assets/images/icons/favicon.ico [NC,L]

# Rewrite appleicon
RewriteRule ^apple-touch-icon.png(.*?)$ /assets/images/icons/apple-touch-icon.png [NC,L]

# Ignore robots.txt
RewriteRule ^robots.txt(.*?)$ /robots.txt [NC,L]

Adding the following to your global.asax:

protected void Application_BeginRequest()
	if (this.Request.AppRelativeCurrentExecutionFilePath.Contains(".mvc"))
		this.Context.RewritePath(this.Request.Url.PathAndQuery.Replace(".mvc", string.Empty));

means you don’t need to have the .mvc in your route configurations, which keeps things nice and tidy!

I try to use natural IDs in my URIs wherever possible, like:


However sometimes this is not always practical, and for many of the non-public facing applications I work on it is simply unnecessary. In these cases I tend to use the GUID ID of the requested resource, like:


These 36 character GUIDs are rather ugly, here is a solution to shorten them down to 22 chars, which looks like:


not perfect, but much better.

N.B. My next step to shorten them further is to use a custom GUID algorithm with no machine-specific part to it, which should remove a significant number of bits. In the meantime, however…

First, we’ll introduce a ShortGuid struct based on the class described here.

public struct ShortGuid
	private readonly Guid guid;

	public ShortGuid(Guid guid)
		this.guid = guid;

	public static bool TryParse(string guid, out ShortGuid shortGuid)
		Guid parsed;
			parsed = new Guid(Convert.FromBase64String(guid.Replace("_", "/").Replace("-", "+") + "=="));
				parsed = new Guid(guid);
				shortGuid = new ShortGuid();
				return false;

		shortGuid = new ShortGuid(parsed);
		return true;

	public override string ToString()
		return Convert.ToBase64String(guid.ToByteArray())
			.Substring(0, 22)
			.Replace("/", "_")
			.Replace("+", "-");

	public Guid ToGuid()
		return this.guid;

	public static implicit operator string(ShortGuid guid)
		return guid.ToString();

	public static implicit operator Guid(ShortGuid shortGuid)
		return shortGuid.guid;

All pretty easy stuff. The difficulty comes when trying to get MVC to use and recognise it.

The easiest solution is to use the ShortGuid class on your resources, however the whole “short guid” concept is purely for HTTP. It certainly has no place in your domain, and has questionable presence in your resources (view models).

The next easiest solution is to use a custom route which replaces any GUID route values just before rendering, here is the code:

public class ShortGuidReplacingRoute : Route
	public ShortGuidReplacingRoute(string url, IRouteHandler routeHandler) : base(url, routeHandler)

	public ShortGuidReplacingRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(url, defaults, routeHandler)

	public ShortGuidReplacingRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler) : base(url, defaults, constraints, routeHandler)

	public ShortGuidReplacingRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler) : base(url, defaults, constraints, dataTokens, routeHandler)

	public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
		var dictionary = new RouteValueDictionary();

		foreach(var kvp in values)
			if (kvp.Value.GetType() == typeof (Guid))
				dictionary.Add(kvp.Key, new ShortGuid((Guid)kvp.Value));
				dictionary.Add(kvp.Key, kvp.Value);

		return base.GetVirtualPath(requestContext, dictionary);

You then need to use this class when registering your routes, I made this convenient extension method to make life easier:

public static class RouteExtensions
	public static Route MapGuidReplacingRoute(this RouteCollection routes, string name, string url, object defaults)
		Route route = new ShortGuidReplacingRoute(url, new MvcRouteHandler());
		route.Defaults = new RouteValueDictionary(defaults);
		route.Constraints = new RouteValueDictionary();

		routes.Add(name, route);
		return route;

which you can use almost as normal, like so:

	new { controller = "Home", action = "Index" }

Then all you need is a ShortGuid model binder:

public class ShortGuidModelBinder : IModelBinder
	public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
			ShortGuid shortGuid;
			var valid = ShortGuid.TryParse(bindingContext.ValueProvider[bindingContext.ModelName].AttemptedValue, out shortGuid);

			if (valid)
				if(bindingContext.ModelType == typeof(Guid))
					return shortGuid.ToGuid();

				if (bindingContext.ModelType == typeof(ShortGuid))
					return shortGuid;

		return Guid.Empty;

Which you register in the normal way:

ModelBinders.Binders[typeof (Guid)] = new ShortGuidModelBinder();

Job done :)

I’m fed up of writing:

<%= Html.Encode(bla) %>

throughout my views. Not only is it messy, but ASP.NET’s default behaviour of “be as insecure as possible” means you have to remember to do this everywhere. In addition to this, it simply uses:


underneath, which isn’t particularly good at preventing XSS.

OpenRasta (a brilliant alternative to MVC which you should be using) has an excellent solution to this problem, by using a custom CSharCodeProvider to help with view compilation.

Below is a simplified version of the code OpenRasta uses, demonstrating how you can get automatic HTML encoding of all code expressions in your views. This also works for WebForms.

It uses an IoC service locator to request an arbitrary IHtmlEncoder. This allows you to use whatever encoding library you like, such as Microsoft AntiXss.

public class AutoHtmlEncodingCSharpCodeProvider : CSharpCodeProvider
	public AutoHtmlEncodingCSharpCodeProvider()

	public AutoHtmlEncodingCSharpCodeProvider(IDictionary<string, string> providerOptions) : base(providerOptions)

	public override void GenerateCodeFromStatement(CodeStatement statement, TextWriter writer, CodeGeneratorOptions options)
		var codeExpressionStatement = statement as CodeExpressionStatement;
		if (codeExpressionStatement != null)
			var methodInvokeExpression = codeExpressionStatement.Expression as CodeMethodInvokeExpression;
			if (methodInvokeExpression != null)
				if (methodInvokeExpression.Method.MethodName == "Write" && methodInvokeExpression.Parameters.Count == 1)
					var parameter = methodInvokeExpression.Parameters[0] as CodeSnippetExpression;

					if ((parameter != null) && (!string.IsNullOrEmpty(parameter.Value)))
						parameter.Value = "global::" + GetType().FullName + ".PreProcessObject(this, " + parameter.Value + ")";

		base.GenerateCodeFromStatement(statement, writer, options);

	public static string PreProcessObject(object source, object value)
		if(value is Raw)
			return ((Raw)value).Value;

		var encoder = ServiceLocator.Current.TryGetInstance<IHtmlEncoder>();
		if (encoder != null)
			return encoder.HtmlAttributeEncode(value.ToString());

		return HttpUtility.HtmlAttributeEncode(value.ToString());

public class Raw
	public string Value { get; set; }

	public static explicit operator Raw(string text)
		return new Raw { Value = text };

	public static implicit operator string(Raw output)
		return output.Value;

You need to register this in your Web.config like so:

		<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="MyAssembly.AutoHtmlEncodingCSharpCodeProvider, MyAssembly">
			<providerOption name="CompilerVersion" value="v3.5" />
			<providerOption name="WarnAsError" value="false" />

Then in your pages, you can do this:

<p><%= "<script>alert('i'm encoded, so i wont popup');</script>" %></p>
<p><%= (Raw)"<strong>i'm bold because im escaped with (Raw)!</strong>" %></p>

Which will be rendered as:

<script>alert(‘i’m encoded, so i wont popup’);</script>
i’m bold because im escaped with (Raw)!

There you go!

Because this code has been inspired by/copied from/a modification of code from OpenRasta, according to its license I must reproduce the copyright notice. If you also wish to use this code, you must do the same.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:
 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

In order to use the UrlHelper class in your tests, you need to construct it with a ControllerContext, which consists of an HttpRequest and an HttpResponse. Unfortunately these are quite difficult to construct, as you’ll know if you’ve ever tried. Luckily, the UrlHelper doesn’t use much of these two classes, only a few properties, making them fairly easy to mock.

The first thing you need to do is get your routes, usually declared in your Global.asax MvcApplication

var routes = new RouteCollection();

Then you need to mock an HttpRequest

var request = MockRepository.GenerateStub<HttpRequestBase>();
request.Stub(x => x.ApplicationPath).Return("/");
request.Stub(x => x.Url).Return(new Uri("http://localhost/a", UriKind.Absolute));
request.Stub(x => x.ServerVariables).Return(new System.Collections.Specialized.NameValueCollection());

Then you need to mock the HttpResponse

var response = MockRepository.GenerateStub<HttpResponseBase>();
response.Stub(x => x.ApplyAppPathModifier(Arg<string>.Is.Anything))
    .WhenCalled(x => x.ReturnValue = x.Arguments[0]);

Then you can simply stick these two mocks onto a mock context, and use that to create your UrlHelper instance and set them on the controller you are testing:

var context = MockRepository.GenerateStub<HttpContextBase>();
context.Stub(x => x.Request).Return(request);
context.Stub(x => x.Response).Return(response);

var subjectUnderTest = new MyController(); // this is the controller you are testing

subjectUnderTest.ControllerContext = new ControllerContext(context, new RouteData(), subjectUnderTest);
subjectUnderTest.Url = new UrlHelper(new RequestContext(context, new RouteData()), routes);

Job done.

Now go and use OpenRasta and not have any of these problems.