Click here to Skip to main content
15,881,852 members
Articles / Web Development / ASP.NET

A Useless Custom ASP.NET Value Provider (or Maybe Not That Useless After All)

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
7 Dec 2011CPOL2 min read 14.3K   3  
Implementing a custom ASP.NET value provider

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 is pretty simple:

C#
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 register it in Global.asax as well:

C#
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 referrer 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 referrer 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:

C#
[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 are 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:

C#
public ActionResult ActionUsingReferer(string referer) {
	return Redirect(referer);
}

Unfortunately, header names like User-Agent are not very C# friendly, so you might have to modify your code in order to be able to consume these headers as parameters named, say, user_agent.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer GeekSoft
Lithuania Lithuania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --