A useless custom Asp.Net value provider (or maybe not that useless after all)

So, following my previous post on implementing a custom Asp.Net Value Provider, here is another one.

Request Header Value Provider

Here is a totally useless requirement: add a Value Provider that would let you use your request headers in your actions without calling HttpContext.Current.Request (or something equally unacceptable). This is actually absurdly simple, because we already have a convenient base class, NameValueCollectionValueProvider, that takes a collection and provides its values to the unsuspecting Controller. So, the code it pretty simple:

public class RequestHeaderValueProvider : NameValueCollectionValueProvider {
	public RequestHeaderValueProvider(ControllerContext controllerContext)
		: base(controllerContext.HttpContext.Request.Headers, 
			CultureInfo.CurrentCulture) { }
 
}
 
public class RequestHeaderValueProviderFactory : ValueProviderFactory {
	public override IValueProvider GetValueProvider
(ControllerContext controllerContext) { return new RequestHeaderValueProvider(controllerContext); } }
Note that we need a ValueProviderFactory again. And we need to regiser it in Global.asax as well:
ValueProviderFactories.Factories.Add(new RequestHeaderValueProviderFactory());

Now it's enough to name the action method parameter as the header you need, and you'll get the value automatically.

Writing a test for it

So, I wasn't completely honest with you when I said it was completely useless. Apart from using it in RESTful apps, there is a pretty common need to get the Referer value, mostly for redirecting back to it as part of the Post-Redirect-Get routine. So, we can test two things (using Ivonna of course): that we have our Referer value as an argument, and that we are actually redirecting to it. Both are integration tests, and the second one is testing both our infrastructure and the actual Action method, but who cares:

[Test]
public void TestHeaderProvider() {
	var request = new WebRequest("/Sample/ActionUsingReferer")
		{AutoRedirect = false};
	const string previousurl = "/PreviousUrl";
	request.Headers["Referer"= previousurl;
	var response = new TestSession().ProcessRequest(request);
	Assert.AreEqual(previousurl, 
			response.ActionMethodParameters["referer"]);
	Assert.AreEqual(previousurl, 
			response.RedirectLocation);
}

Notice that we have to disable the Autoredirection feature of Ivonna: without that, we'll be testing the result of the redirection (quick poll: do you want this property to be false by default?), rather than the original request. Notice that we ae using the new MVC feature of Ivonna: the ability to get the action method parameters.

Finally, here's the code that makes this test happy:

public ActionResult ActionUsingReferer(string referer) {
	return Redirect(referer);
}
Unfortunately, header names like User-Agent are not very C# friendly, so you might have modify your code in order to be able to consume these headers as parameters named, say, user_agent.
blog comments powered by Disqus

Latest blog posts

Powered by FeedBurner

Archives