views:

180

answers:

2

I am migrating a web site to a new one using ASP .NET MVC2.

In the original site, master page has code-behind to check a query string parameter value. Depending on this value, code-behind dynamically modify some CSS property to hide / display master page elements.

As MVC2 has no code-behind because we are supposed to perform everything in the controllers, how should I proceed in this case ?

I see this : http://stackoverflow.com/questions/3671956/asp-net-mvc-modifying-master-file-from-a-view

It partially answers my needs but the query string processing is common to all pages. How can I move this processing in a common code section ?

Regards.

+1  A: 

A helper method looks like a good place:

public static class HtmlHelperExtensions
{
    public static string GetCss(this HtmlHelper htmlHelper)
    {
        // read some request parameter
        // here you also have access to route data so the
        // parameter could be part of your custom routes as well
        var foo = htmlHelper.ViewContext.HttpContext.Request["foo"];

        // based on the value of this parameter 
        // return the appropriate CSS class
        return (foo == "bar") ? "barClass" : "fooClass";
    }
}

And somewhere in your master page:

<body class="<%= Html.GetCss() %>">

Or if you are always going to apply it to the body tag only it might be more appropriate to do this in order to reduce the tag soup:

public static class HtmlHelperExtensions
{
    public static MvcHtmlString StartBody(this HtmlHelper htmlHelper)
    {
        var body = new TagBuilder("body");
        var foo = htmlHelper.ViewContext.HttpContext.Request["foo"];
        var bodyClass = (foo == "bar") ? "barClass" : "fooClass";
        body.AddCssClass(bodyClass);
        return MvcHtmlString.Create(body.ToString(TagRenderMode.StartTag));
    }
}

and in your master page at the place of the body tag:

<%= Html.StartBody() %>
Darin Dimitrov
Thanks. It seems nice.
Sylvain
A: 

I can think of two solutions to this:

  1. Derive your controllers from one controller base and set the ViewData parameter there depending on posted Form values

  2. Don't use ViewData at all, but simply look for the form value in the view (using HttpContext.Current)

The second method violates the MVC pattern. IMO it is still acceptable in some scenarios, for example I am using this approach to highlight the currently selected item in a navigation menu.

Adrian Grigore
Hello Adrian, about #1, I considered it but I read that Request object was not accessible (I have not tried so far) in base controller. #2 is the easiest way, I agree. But as you said, I would like to avoid violating MVC pattern (if possible). Thanks.
Sylvain