I'm building a generic web application for two business groups. The logo/banner needs to be changed based on the querystring. For example, if the url is http://foo.com/test?bg=a it shows the logo for business group a and if the url is http://foo.com/test?bg=b it shows the logo for business group b. This is not a problem if I only had one action. But I have many actions.
I could check the query string on all actions but there must be a nice way to do it. I have an perception that I need to do something with the routing stuff but just don't know how. Can anyone please let me know how to do it?
You can write a Custom Routing Handler and use routing to extract the querystring as a parameter, and pass into RouteData where it can be accessed anywhere.
public class RouteWithQueryStringValueHandler : MvcRouteHandler
{
private readonly string key;
public RouteWithQueryStringValueHandler(string key)
: base()
{
this.key = key;
}
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var request = requestContext.HttpContext.Request;
var qsValue = requestContext.HttpContext.Request[key];
var router = base.GetHttpHandler(requestContext);
requestContext.RouteData.DataTokens[key] = qsValue;
return router;
}
}
Register as follows:
routes.Add(new Route("{controller}/{action}/{id}",
new RouteValueDictionary(
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional
}),
new RouteWithQueryStringValueHandler("bg")));
Get the logo for Routing data:
var logo = RouteData.DataTokens["bg"];
You could write a custom helper method which based on the query string parameter will append a given class name to some div. Then of course you would have different class definitions in your CSS file applying a background-image.
For example:
public static class HtmlExtensions
{
public static string BannerClass(this HtmlHelper html)
{
var bg = html.ViewContext.Controller.ValueProvider.GetValue("bg");
if (bg == null || string.IsNullOrEmpty(bg.AttemptedValue))
{
// no bg parameter => return a default class
return "default_banner";
}
if (string.Equals("a", bg.AttemptedValue))
{
return "banner_a";
}
else if (string.Equals("b", bg.AttemptedValue))
{
return "banner_b";
}
// unknown value for the bg parameter => return a default class
return "default_banner";
}
}
and then in your _Layout you could apply this class to some placeholder like a div or even the body:
<div class="@Html.BannerClass()">OK</div>
This way it will always be applied for all view in your application.
Now all that's left is to define your CSS rules for the different banners:
.default_banner {
background-image: url('../images/default_banner.png')
}
.banner_a {
background-image: url('../images/banner_a.png')
}
.banner_b {
background-image: url('../images/banner_b.png')
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With