views:

207

answers:

2

We have a fairly complex application that was previously using WebForms. We are in the process of rewriting bits of it from scratch using MVC. Our application is comprised of a number of widgets, that together make up the functionality of the application.

In WebForms, we used UserControls. Each UserControl would register its CSS and JavaScript by means of a collection that was stored in HttpContext.Current.Items. That collection would then be merged to output as one single request. Typically this would occur in the Page_Load event, and the containing page would then render out a script tag that would comprise all the JavaScript and CSS needed for that page.

We've been struggling with doing the same in MVC. We are using a number of views within a masterpage to mimic the widgets. Each widget has its own controller, so the functionality can be sufficiently segregated. The masterpage builds up the widgets on the page using RenderAction from MVC futures. Originally we were using the same registration method for the CSS/JS files. Each controller would register its required files in an Action. The files would then be contained in the HttpContext.Current.Items collection, and would be rendered out to the page. To facilitate this, I wrote an HtmlHelper extension to render the links/scripts out to the page. It looks like this:

<%= Html.GetRegisteredCssFiles() %>

The problem is that MVC uses a more top down approach. This call is made in the tag of the page, but our subsequent calls to RenderAction happen below. By the time RenderAction is called and the required files are registered in HttpContext.Current.Items, the code above has already executed. So, the collection is not modified at the right time.

Does anyone have any ideas on how we should be constructing this? I'm looking for answers that incorporate best practices for MVC.

A: 

Not sure if this is a feasible solution for you, but try moving that call to the bottom of each page.

I've always included my javascript and css files in the html HEAD, so I don't know if it would work lower down. My assumption is that it'll work in most browsers, but you might have random problems in a few.

The alternative is to have GetRegisteredFiles() output some javascript that loads the CSS files in the proper place (via DOM manipulation).

The problem with either of these solutions is that the files aren't included until the end, which could cause the page to look "plain" until the CSS is downloaded.

Alternatively, the controller could predict which "widgets" will get loaded and pass that data to the master page.

James S
+1  A: 

The Free Telerik MVC tools have a script and a style register that might do what you want ...

Hurricanepkt
Ya I noticed that recently. I've checked it out but I don't think it will facilitate registering scripts in alternate controllers. Will dig it and check out.
steve_c