1

Question

In ASP.NET MVC (and specifically with Razor), how does one set the value of a variable within a partial (or "sub-template") and access that value within a master (or layout) template?

Goal

I would like to maintain lists of assets (stylesheets and JavaScript files) and be able to add to the lists from within partials. The assets should then be accessible within the master layout to be included in the <head/> (stylesheets) or near the end of the <body/> (JavaScript files) of the page. This provides an elegant means of storing modules in partials that include all necessary assets.

My Attempt

Below is what I have tried for stylesheets. The intended result is that both global.css and view_post.css would be included in the header, but only global.css is showing up. It is my understanding that this occurs because the layout is rendered before the template.

Helpers/AssetHelper.cs

namespace MyApp.Helpers
{
    public static class AssetHelper
    {

        private static SortedSet<string> StyleSheets(this HtmlHelper helper)
        {
            if (helper.ViewBag._styleSheets == null)
                  helper.ViewBag._styleSheets = new SortedSet<string> ();
            return helper.ViewBag._stylesheets as SortedSet<string>;
        }

        public static MvcHtmlString AddStyleSheet(this HtmlHelper helper, string styleSheet) {
            helper.StyleSheets().Add(styleSheet);
            return new MvcHtmlString("");
        }

        public static MvcHtmlString RenderStyles(this HtmlHelper helper)
        {
            StringBuilder output = new StringBuilder();
            string template = "<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\" />";

            foreach (string styleSheet in helper.StyleSheets())
                output.Append(String.Format(template, styleSheet));

            return new MvcHtmlString(output.ToString());
        }

    }
}

Views/Shared/Layout.cshtml

@using MyApp.Helpers

<html>
  <head>
    ...
    @Html.AddStyleSheet("global.css")
    @Html.RenderStyles()
  </head>
  <body>
    ...
    @RenderBody
    ...
  </body>
</html>

Views/Posts/View.cshtml

@using MyApp.Helpers
@Html.AddStyleSheet("view_post.css")

<h2>...</h2>
<p>...</p>
2
  • Duplicate of these three questions. I just needed the Related sidebar after posting my question. :) Commented May 7, 2013 at 1:02
  • None of those answer actually answer the question you asked. They are simply ways to set the css or scripts via children, and have nothing whatsoever to do with setting a variable in a partial and using it in a parent (the question you asked about). Commented May 7, 2013 at 1:14

1 Answer 1

4

You can't. Layout templates are rendered before your partials. Any variable you set in a partial will be set too late for the layout to know it's there.

This seems like an over complex solution. Why don't you just use the WebOptimization tools that MVC provides?

Sign up to request clarification or add additional context in comments.

3 Comments

Saying you can't do something does not answer how to do it. And just because you don't know how doesn't mean it is not possible.
@AndrewAshbacher - It's absolutely not possible to set a c# variable in a partial and use it in a layout. Downvoting me for answering the question you asked (rather than the question you seem to have meant) is very poor netiquette. Yes, you can set scripts in the layout in a number of ways, but not via the question you specifically asked.
Fair enough. I'll be sure to phrase the actual question appropriately in the future. That said, this is not an overly complex solution as it simplifies a great deal of code elsewhere. We are using something similar to WebOptimization. But, we would like to also modularize and improve reusability of our code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.