Hugoware

The product of a web developer with a little too much caffeine

Adding Stylesheets, Scripts In ASP.NET MVC2

with 9 comments

A while back I worked on some code that allowed you to add content to different areas of a MVC view, specifically for dealing with headers and scripts. The code worked well enough but relied on a lesser used member in the Reponse class – the Filter property.

Except, now in MVC2 you see this little message when you try to mess with the Filter…

Filtering is not allowed? What? Why not?!?

Admittedly, the original solution was rather hackish because it tried to perform all of the work in the Render phase of the page life cycle and then update the correct content areas in a custom stream that as assigned to the Filter property. You could only pass content as a string value so it mean’t a lot of ugly escaping of characters instead of simply writing normal HTML.

Lately, I’ve been working on another personal project related to templating MVC pages. I won’t give away too much for now but let’s just say that I think that Web Controls still have great potential. Sometimes a page layout takes a couple passes to ensure everything is where it needs to be which is something that the page life cycle handles for you.

Let’s look at another example that uses Web Controls to update content in different parts of the page.

[Download Source Code: ContentArea / ContentDisplayArea] – Remember, I’m posting code on github.com and specifically using gist – If you aren’t using it then you might want to check it out! I hacked out this code this evening so if you discover bugs then feel free to report them to me. (and considering the developer who wrote it, you probably will) šŸ™‚

After you’ve added the code to your project you’re going to have to add a reference to the controls by adding an entry to your web.config. It will look something like the example below.

<?xml version="1.0"?>
<configuration>
    <!-- Snip... -->
    <system.web>
        <pages>
            <controls>
                <!-- Snip... -->
                <add tagPrefix="mvc" namespace="MvcWebControls" assembly="YourProjectName" />
            </controls>
        </pages>
    </system.web>
</configuration>

So, now you have the controls added let’s pretend we have a view that looks like the example below and we want to add a few stylesheets to it.

[View.aspx]

<% @Page ... %>
<html>
    <head>
        <title>My Mvc Application</title>

        <!-- Consumes the content of areas with a target named 'header' -->
        <mvc:ContentDisplayArea ID="header" runat="server" />

    </head>
    <body>
        <% this.Html.RenderPartial("SomeControl.ascx"); %>
    </body>
</html>

And then in our partial control we use a ContentArea to add content to the header.

[SomeControl.ascx]

<% @Control ... %>

<mvc:ContentArea runat="server" Target="header" >
    <link rel="stylesheet" src="<% =this.Url.Content("~/resources/somecontrol.css") %>" />
</mvc:ContentArea>

<div class="control-container" >
    Hello World... uh... nevermind...
</div>

An just like that our content appears in the header of our page! Excellent!

How does it work? Some sort of magic? Maybe a fancy, super technical programming trick?

… or maybe it just uses the existing ASP.net functionality to track controls, render content and then move them to the correct containers by linking into different phases of the page life cycle. Not exactly ‘magical’ and somewhat anti-climatic but definitely reminds us that while MVC is the new hawtness it still is ASP.NET.

Anyways, in the next few weeks I’ll share more about my thoughts for alternative ways to create views in MVC and my new templating project… but for now try out the code and enjoy!

Written by hugoware

April 6, 2010 at 10:48 pm

9 Responses

Subscribe to comments with RSS.

  1. Can’t for the life of me get this to work. I created a new MVC 2 application (the RC), downloaded the MvcWebControls and added it directly to the project, create a page and control exactly as above and added the line to the web.config – no go. Nothing was rendered in the html. Did you use beta or was this test on RC (and maybe you missed including in the article some key thing)?

    Thanks, Tim

    Tim

    July 2, 2010 at 2:33 pm

    • Tim, there has been some problems with some of my old code not working with MVC2 – I think a lot of it can be fixed by overriding the ViewContext.Writer property instead of the rendering method in the code now. I’ll have to test it more to be sure.

      hugoware

      July 3, 2010 at 8:00 pm

  2. Working for me, thanx for sharing it. I use it to bunch javascript at the end of the page. But, it has one drawback – if I place the mvc:ContentArea control inside a conditional block:

    do something here

    alert(“hello”);

    it still put the content into the page even if the user not logged in. Any idea how to handle it? Cheers.

    xhafan

    September 26, 2010 at 6:13 pm

  3. Previous post is missing tags. Just imaging a situation in the mvc view, if user is logged in, then render mvc:ContantArea . Regardless user is logged in or not, is still puts the content into the page.

    xhafan

    September 26, 2010 at 6:19 pm

    • Most likely you can simply put the user content inside of a server side render block of code (it has been a while, but it should work)


      <mvc:ContentArea ...>
      <% if(user.IsLoggedIn) { %>
      Logged in...
      <% } %>
      </mvc:ContentArea>

      hugoware

      September 27, 2010 at 12:59 am

  4. Thank you very much! šŸ™‚

    E.T

    November 11, 2010 at 10:43 pm

  5. I cannot get a ContentDisplayArea to render in MVC 2. I noticed your comment to Tim… my issue seems to be similar to his.

    Suggestions?

    Jon Scalet

    January 21, 2011 at 10:26 pm

    • What exactly is the issue you’re running into? Are you getting any exception messages?

      hugoware

      January 22, 2011 at 10:38 am

      • I actually was able to get it working.. trouble is I’m trying to use a ContentArea within a PartialView that is rendered using RenderAction rather than RenderPartial.

        I’m assuming that once the PartialView calls the action method we lose the ability to Render a ContentArea. I’ve been running around all morning trying to figure out how to setup debugging so I can step into System.Web.Mvc to get a better idea of the life cycle. Any suggestions?

        Jon Scalet

        January 22, 2011 at 12:35 pm


Leave a comment