Skip navigation

Category Archives: .Net

I’m in the process of moving my email handling from google apps over to mailgun, mainly because I really need web hooks to support new customer dashboard functionality.

Since my search for some proper .Net library resulted in basically nothing, I decided to roll one myself: mnailgun (I know, the ‘n’ should come first, but I liked this version more ;-P). And while I was at it, I thought, well why not do it in the open as well? So here you go: The source code is available on github and a nuget package is available as well.

For some reason searching for ‘mnailgun’ on the nuget site results in an empty list, while searching for it in Visual Studio when adding a package reference, seems to work just fine… Anyone know why?

If, for whatever reason (I’m not going into this discussion), you’d like to inject your dependencies at the method level instead of using your constructor, like so:


public ActionResult Post(Whatever whatever, IMyDependency dependency)
{
	// use dependency here
}

Just create these two classes:

public class DependencyModelBinderProvider : IModelBinderProvider
{
	public IModelBinder GetBinder(Type modelType)
	{
		return modelType.IsAbstract ? new DependencyModelBinder() : null;
	}
}

public class DependencyModelBinder : IModelBinder
{
	object IModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
	{
		return DependencyResolver.Current.GetService(bindingContext.ModelType);
	}
}

And, of course, at bootstrap/app start time:

ModelBinderProviders.BinderProviders.Add(new DependencyModelBinderProvider());

Voilà, DI at method level in 2 minutes!

I was almost going crazy before I found out that when you use a PreApplicationStartMethodAttribute for bootstrapping your hosting environment you must point to a type that resides in the same assembly that is being decorated!

Pointing to types in a different assembly will just blow up with a YSOD saying ‘The method specified by the PreApplicationStartMethodAttribute on assembly ‘assembly name’ cannot be resolved. Type: ‘type name’, MethodName: ‘Initialize’. Verify that the type is public and the method is public and static (Shared in Visual Basic).’.

Just though I’d mention it here, there’s not to much info on this…

There’s quite some annoyence about how ASP.Net routing handles trailing slashes. I agree, it would have been nice if one could enforce whether or not to use a trailing slash.

I’ve always taken good care of my trailing slashes. Almost every link comes from my custom UrlHelper or extension methods (for convenience – e.g. Model.Product.GetThumbnailUrl()). Anyway, that doesn’t mean it stopped bugging me! For one, external links (SEO) are not under your control, I don’t really know how serious this duplicate content issue is, but I’m not willing to take a chance on it. Another unsolved annoyence is when you add content pages. You always have to think twice about trailing slashes in every little link you include.

This week, I thought it was about time to go for a more generic solution. I started by googling for it and almost ended up using the new IIS7 URL Rewrite Module just like Scott suggested in his post. The main reason I didn’t was because I hate managing things in two places. Especially when their so closely related.

And then I thought: Why not let the system do what you ask it to do? How hard can it be to make the system respect you route mappings? If I map a route with url "{category}/" or "{category}/{product}" I want to make sure category urls end with a slash and products don’t. That simple.

It seemed to me that tuning ASP.Net MVC’s UrlRoutingModule was the most abvious thing to do, so here’s what I’ve done:

public class UrlRoutingModule : System.Web.Routing.UrlRoutingModule
{
	private const string SLASH = "/";

	public override void PostResolveRequestCache(HttpContextBase context)
	{
		var routeData = RouteCollection.GetRouteData(context);

		var redirecturi = GetRedirectUri(routeData, context.Request.Url);

		if (redirecturi != null)
		{
			context.Response.RedirectPermanently(redirecturi);
			return;
		}

		base.PostResolveRequestCache(context);
	}

	private static Uri GetRedirectUri(RouteData routeData, Uri requestedUri)
	{
		if (routeData == null) return null;

		var route = routeData.Route as Route;
		if (route == null) return null;

		var requestedSegments = GetSegmentCount(requestedUri.AbsolutePath);
		var mappedSegements = GetSegmentCount(route.Url);

		if (requestedSegments == mappedSegements)
		{
			var slashRequired = route.Url.EndsWith(SLASH);

			if (slashRequired && !requestedUri.AbsolutePath.EndsWith(SLASH))
				return requestedUri.Append(SLASH);

			if (!slashRequired && requestedUri.AbsolutePath.EndsWith(SLASH))
				return requestedUri.TrimPathEnd(SLASH[0]);
		}
		else if (!requestedUri.AbsolutePath.EndsWith(SLASH)) // requestedSegments < mappedSegements
		{
			return requestedUri.Append(SLASH);
		}

		return null;
	}

	private static int GetSegmentCount(string path)
	{
		return path.Split(SLASH.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length;
	}
}

Note: If your route ends with optional segments, urls that don’t include them always end up with a trailing slash.

Another note: The Append and TrimPathEnd are Uri extension methods:

public static class UriExtensions
{
	public static Uri Append(this Uri uri, string value)
	{
		return new Uri(GetAbsoluteUriWithoutQuery(uri) + value + uri.Query);
	}

	public static Uri TrimPathEnd(this Uri uri, params char[] trimChars)
	{
		return new Uri(GetAbsoluteUriWithoutQuery(uri).TrimEnd(trimChars) + uri.Query);
	}

	private static string GetAbsoluteUriWithoutQuery(Uri uri)
	{
		var ret = uri.AbsoluteUri;
		if (uri.Query.Length > 0) ret = ret.Substring(0, ret.Length - uri.Query.Length);
		return ret;
	}
}

One more note:: I’m fully aware that this module alone does not solve the entire trailing slash problem, but minor additional (possibly project-specific) things like a custom UrlHelper (what I did/had to do, I spare you the details) or solutions like this method are easy enough to make it complete.

I just read Jimmy Bogard’s post on how we do MVC ViewModels and I must say, I digg the approach. Personally, I find it a shame that the ViewData dictionary is so damn prominent.

In the comments there was a little bit of discussion on how to handle the ViewModel for the master page. Since there wasn’t much of elaboration on the topic, I thought I’d mention how I’m doing it for quite a while now, and I’m still ok with it :-).

I chose to use a ViewModel base class for the master page with the following in mind:

  • The base class only contains information that makes sense for every view page that is using the particular master page.
  • Just like Jimmy explains in his post, I also have very specific requirements. I’m not only talking about XHTML et. al., but things like unique titles, etc.
  • I’ve got my app split up in independent modules. The only thing they’ve got in common, is a base class for initialization and the fact that their views reside in the same project/directory structure on disk. This means that when I’m working in module X, I know what my master page and its (ViewModel-) requirements are and can subclass ViewModel as I see fit.

Before I continue: I certainly do not put ALL view model data of the master page in the base class, don’t get me wrong. There is quite some information that’s rendered by the master page, but that information is not coming from its model. Most things come from composed RenderActions (not partials!). Only view data that can be/needs to be provided by distinct action methods is defined in the base class. Every master page in my app (typically, one per module) inherits from ViewMasterPage<ViewModel> where ViewModel looks something like this:

/// <summary>

/// Represents the model that contains information for the view.
/// </summary>
public class ViewModel
{
	private readonly HtmlHeader header = new HtmlHeader();

	/// <summary>
	/// Represents the information for the (X)HTML head element.
	/// </summary>
	public HtmlHeader HtmlHeader { get { return header; } }
}

I guess it’s no surprise that to you that HtmlHeader looks like this (in my case):

public class HtmlHeader
{
	public string Title { get; set; }
	public string MetaDescription { get; set; }
	public string MetaKeywords { get; set; }
}

My master page itself uses the ViewModel as follows:

...
<head>
	<title><%= Html.Encode(Model.HtmlHeader.Title ?? Resources.Master.DefaultPageTitle) %></title>
	<meta name="description" content="<%= Html.Encode(Model.HtmlHeader.MetaDescription ?? Resources.Master.DefaultMetaDescription) %>" />

	<meta name="keywords" content="<%= Html.Encode(Model.HtmlHeader.MetaKeywords ?? Resources.Master.DefaultMetaKeywords) %>" />
	...
</head>
...

This model only contains information that is to be supplied by action methods. When an end user requests product information, the action method must provide the title, META keywords etc. When a user requests a content page, the ViewContent(string slug) method is responsible for getting the content and map its title, META description, author, copyright, etc. to the ContentViewModel.

But how can we be sure?

Ok so far so good, we’ve organized ourselves a bit, but how can we make sure we return the proper type of view model? Due to the loose coupling between the M, V and C and the way ControllerBase and Controller are designed, it practically requires a rewrite (encapsulation if we’re lucky) of the existing hierarchy…

But then again, if you’re doing TDD, you should be fine (’the_view_model_should_…’). If you’re not, the very first HTTP GET will blow up, so you’ll know something’s wrong soon enough either way. So, why go through all this hassle?

This does not mean there’s nothing that can’t be done! But before I (try to) do, I’m going to address my SRP issue! I currently investigating things like commands in stead of controllers and ActionControllers and how to fit in the ViewModel (maybe).

I’m just done updating my expression routing extensions class: First I’ve added support for extraction default values from Nullable parameters (oh boy, how could I miss that one!). Second, and more interestingly maybe, I’ve added support for automatically extracting constraints.

Let’s say you’ve got this route:

routes.MapRoute<ProductsController>(
	"brands/{title}-{brandId}/{pageIndex}",
	c => c.Brands(0, 0),
	cultureNames,
	null,
	new { brandId = @"\d+", pageIndex = @"\d+" });

The two regex values are there to ensure that request for ~/brands/somebrand-1/foo or ~/brands/somebrand-bar/1 are never even forwarded to the action method. It is part of the contract and does not make sense. (I have setup my routing in such a way that the final fallback/wildcard route maps to a content management module that renders a ‘page not found’ if the slug cannot be found in the database.)

If you take a look at the action method Brands(int, int?) you’ll see that it is perfectly possible to deduct these constraints from the expression. I decided to add support for this as follows:

  • Explicit constraints (passed to the MapRoute method), always win
  • If the type of the parameter is IConvertible (including nullable types), I automatically add a constraint
  • Strings parameters are ignored

Just like the GetActionDefaults, I’ve added a GetActionConstraints, that parses the method call as follows:

private static RouteValueDictionary GetActionConstraints(MethodCallExpression call, RouteValueDictionary constraints)
{
	if (constraints == null) constraints = new RouteValueDictionary(); 

	foreach (var parameter in call.Method.GetParameters())
	{
		// if there's an explicit constraint, keep it, if it's a string, just ignore it
		if(constraints.ContainsKey(parameter.Name) || parameter.ParameterType == typeof(string)) continue;

		var converter = TypeDescriptor.GetConverter(parameter.ParameterType);
		if(converter != null && converter.CanConvertFrom(typeof(string)))
		{
			constraints.Add(parameter.Name, new ConversionTestConstraint(converter));
		} 

		return constraints;
	}
}

The method adds a ConversionTestConstrating that takes the specific converter (we need this, since we can’t be sure we will be able to determine the type (or converter) the moment the constraint is called.

The ConversionTestConstraint is somewhat ugly, I admit, but in my defense: I have to catch a general Exception because most TypeConverters are implemented badly (in my opinion). The conversion will rarely fail, so I guess it’s not the end of the world, but still.

public class ConversionTestConstraint : IRouteConstraint
{
	private readonly TypeConverter converter;

	public ConversionTestConstraint(TypeConverter converter)
	{
		this.converter = converter;
	}

	public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
	{
		if (!values.ContainsKey(parameterName)) return true;

		try
		{
			converter.ConvertFrom(values[parameterName]);
			return true;
		}
		catch (Exception) // WTF?! ConvertFrom throws System.Exception with FormatException as InnerException
		{
			return false;
		}
	}
}

Now I can simply put the following, with the same result:

routes.MapRoute<ProductsController>(
	"brands/{title}-{brandId}/{pageIndex}",
	c => c.Brands(0, 0),
	cultureNames);

In yeterday’s post, I mentioned that I would give the IDataContractSurrogate a try to solve this issue. And guess what? Problem solved! Mine anyway, I’m not sure if it will help in all cases, but certainly for this one about arrays.

I started with a pass-through/noop implementation just to see if I could hook into the serialization process hoping to get some more insight. What I noticed was that GetObjectToSerialize got called several times before the exception was thrown. In the second run, I kept track of the parameter values and found out that I overlooked an IList<T> property somewhere deep in the object graph of the data contract. Since the property value was deserialized after retrieval over the wire it was now, of course, just a simple array…

Microsoft proposed to work around the issue by putting the data contract assembly in the GAC, however, there’s a much simpler solution: modify your object while it is being serialized.


public object GetObjectToSerialize(object obj, Type targetType)
{
	if (obj is Array && targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(IList<>))
	{
		var typeArg = targetType.GetGenericArguments()[0];  // typeof(T)
		var type = typeof(List<>).MakeGenericType(typeArg); // typeof(List<T>)
		return Activator.CreateInstance(type, obj);         // new List<T>(IEnumerable<T>)
	}

	return obj;
}

Put this in your IDataContractSurrogate implementation, pass it to the constructor of your serializer and you should be good to go. Every time the serializer is about to serialize an array (T[]) the surrogate will give it a wrapper (List<T>) instead.

The funny thing about all this is that it is not the first time I had to implement an IDataContractSurrogate, but for completely different reasons. The fact that my original unit test worked and that the bug was only triggered when running in IIS (or Cassini) and that putting the assembly in the GAC solved it got me so confused, that I only though about going the surrogate way later that day. I still wonder why putting the assembly in the GAC, solves the problem, though. And what’s got LoaderOptimization to do with it? The CLR moves in mysterious ways, I suppose, at least sometimes…

Lost a few hours on this one today! Here’s what happened: At some point in our application I get hold of an object graph (an instance of a DataContract) which I need to serialize and store in the database. No big deal, I thought…

As any good citizen, I started with a test. First a unit test, then a minor integration test. Fine, time to put it in the app. After doing so, however, both Cassini and IIS died on me with an ExecutionEngineException as soon as WriteObject got called. WTF?!

Apparently, there’s this bug that’s been bugging me today:

When data contract contains property of type IEnumerable<T> where T is another data contract .NET crashes after handling the request (.NET crashes after operation method is invoked and returns the result).

If a OperationContract is defined to return IList<T> where T is a type defined by a DataContract, and an array is returned, then WCF throws an ExecutionEngineException.

Both entries are describing a somewhat different context, but I was sure it was the same problem. Since I was using a shared assembly, I didn’t have the freedom to ‘play around’ with the data contracts to see if I could do something about it. What I did notice, though, was that I was able to serialize other, far more complex, data contract without any problem. Also, the data contracts has concrete Lists defined, not interfaces. Weird.

Anyway, putting the shared assembly in the GAC, did indeed solve the problem. Five minutes later someone tells me (I’m new there) we’re not allowed to put assemblies in the GAC on our servers… ain’t that just sweet? I think I’m gonna give the IDataContractSurrogate a try tomorrow, one never knows.

Update: I’ve added automatic constraints to this.

When you’re working with ASP.Net MVC, routing is a very important thing to get just right. Unfortunately, the default routing options are pretty fragile. By default you have to resort to ‘magic strings’, anonymous types and/or string-based dictionaries etc. Depending on your requirements, this kind of routing can become quite the PITA.

Looking at my personal requirements: I have about 120 routes to map (including localization and a fall-back to managed content in the database). One day I got so fed up with the default routing options, that I decided to go for my own MapRoute() extension method.

Here’s just a fraction of my current RegisterRoutes() method (I’ve removed localization, for simplicity):

routes.MapRoute<ProductsController>("search/{query}/{pageIndex}", c => c.Search("", 0));
routes.MapRoute<ProductsController>("new/{pageIndex}",            c => c.NewProducts(0));
routes.MapRoute<ProductsController>("soon/{pageIndex}",           c => c.ComingProducts(0));

Before my changes it looked like this (again, without localization; with localization, there would be 3 more per route):

routes.MapRoute("Search", "search/{pageIndex}", new { controller = "Products",	action = "Search", pageIndex = 0 });
routes.MapRoute("newproducts", "new/{pageIndex}", new { controller = "Products", action = "NewProducts", pageIndex = 0 });
routes.MapRoute("soonproducts", "soon/{pageIndex}", new { controller = "Products", action = "ComingProducts", pageIndex = 0 });

Notice the difference?

Getting rid of magic strings was not my only motivation, though. I have chopped-up my application in different modules. The two main modules are the actual customer front-end and the administrative product/category/brand/news/foo/bar management pages. As it happens, both have a ProductsController class… If you go for default routing, you’ll run in to issues: ASP.Net MVC won’t be able to distinguish the one class from the other and throw you a nice exception telling you to specify the namespaces to disambiguate the controllers. The default solution would be specifying the namespace using magic strings, yet again…

Here’s the extension method (the most extended overload):

public static void MapRoute<T>(this RouteCollection routes, string url, Expression<Func<T, ActionResult>> action, RouteValueDictionary defaults, RouteValueDictionary constraints)
	where T : Controller
{
	if (routes == null) throw new ArgumentNullException("routes");
	if (url == null) throw new ArgumentNullException("url");
	if (action == null) throw new ArgumentNullException("action");

	var methodCall = action.Body as MethodCallExpression;
	if (methodCall == null) throw new ArgumentException(string.Format("The action '{0}' does not represent a method call.", action), "action");

	// merge action defaults with explicit defaults
	defaults = GetActionDefaults(methodCall, defaults);

	// verify constraints
	if(constraints != null && constraints.Any(c => !(c.Value is IRouteConstraint || c.Value is string)))
		throw new ArgumentException("The constraints dictionary contains illegal elements. Constraint values must be strings (regex) or IRouteConstraint implementations.", "constraints");

	var route = new Route(url, new MvcRouteHandler())
	{
		Defaults = new RouteValueDictionary(defaults),
		Constraints = constraints,
		DataTokens = new RouteValueDictionary { { NamespacesKey, new[] { typeof(T).Namespace } } }
	};

	routes.Add(url, route);
}

Here’s the GetActionDefaults method that extracts the default values from the method signature:

private static RouteValueDictionary GetActionDefaults(MethodCallExpression call, RouteValueDictionary defaults)
{
	var controllerName = call.Method.DeclaringType.Name;
	if (controllerName.EndsWith(ControllerSuffix, StringComparison.OrdinalIgnoreCase))
		controllerName = controllerName.Remove(controllerName.Length - ControllerSuffix.Length, ControllerSuffix.Length);

	defaults.Add(ControllerKey, controllerName);

	var attributes = call.Method.GetCustomAttributes(typeof(ActionNameAttribute), true);
	defaults.Add(ActionKey, attributes.Length == 1 ? ((ActionNameAttribute) attributes[0]).Name : call.Method.Name);

	var parameters = call.Method.GetParameters();
	for (var i = 0; i < parameters.Length; i++)
	{
		var expression = call.Arguments[i] as ConstantExpression;
		if (expression != null) defaults.Add(parameters[i].Name, expression.Value);
	}

	return defaults;
}

Result:

  • Who needed that route name anyway?
  • No more magic string (except fot the url)
  • Namespaces are registered automatically, modules/areas no longer require special treatment
  • Defaults are resolved from the action expression (additional defaults are still suppported)
  • Constraints are checked as soon as the route is mapped (as good as it gets, I suppose)
  • If you’re happy with ‘http://domain.com/{cultureName}/…’ url’s, you’re good to go as well, just pass along an array of supported culture names:
public static void MapRoute<T>(this RouteCollection routes, string url, Expression<Func<T, ActionResult>> action, string[] cultureNames, RouteValueDictionary defaults, RouteValueDictionary constraints)
	where T : Controller
{
	routes.MapRoute(url, action, new RouteValueDictionary(defaults), constraints);

	foreach (var cultureName in cultureNames)
	{
		var d = new RouteValueDictionary(defaults) {{"lang", cultureName}};
		routes.MapRoute(string.Format("{0}/{1}", cultureName, url), action, d, constraints);
	}
}

Man, since about a week now, I’m forced at using ASP.Net WebForms. It’s been so long, that I almost forgot what a terrible PITA WebForms really is.

I can only hope I get them to move to something else real soon…

Follow

Get every new post delivered to your Inbox.