tags:

views:

787

answers:

4

I'd like to add a little variablility onto the path of my css link everytime my Site.Master view is processed. What is the correct way to do this? My code currently breaks on the Default.aspx saying I have not defined cssLink. Site.Master code below:

    <script runat="server">
        void Page_Load(object sender, EventArgs e)
        {

            string cssLoc = "../../Content/css/expect.css?t=" + DateTime.Now.Ticks.ToString();
            string cssLink = String.Format(@"<link rel=""stylesheet"" type=""text/css"" href=""{0}"" />", cssLoc);
        }
    </script>

    <!DOCTYPE html>
    <html>
    <head id="Head1" runat="server">   
        <asp:ContentPlaceHolder ID="head" runat="server">
        <title></title>
        </asp:ContentPlaceHolder>    
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <%= cssLink %>
        <script type="text/javascript" src="../../Scripts/jquery.js"></script>
    </head>

Also, is there anyway to fix the "XHTML transitional, Title occurs too few times" message?

UPDATE:
Please ignoring the scoping issue. See Richard's answer. I should note however that fixing this does not solve the issue.
I think because of the Inherits="System.Web.Mvc.ViewMasterPage" declaration the entire
<script runat="server"> block does not get processed.

+5  A: 

Just define your css link like you typically would and add some inline processing. You are attempting to do a Page_Load within a MVC view which is not a workable solution...

<link href="../../Content/css/expect.css?t=<%=DateTime.Now()%>" type="text/css" rel="Stylesheet" />
Jason
I use Page_Load to handle some legacy controls in an MVC app I work on and it works just fine. It's not pretty and shouldn't be used if you don't need it, but it is there.
Stuart Branham
Stuart, really. The Page_Load did not work for me. Even after I fixed the scoping issue.
tyndall
I'm not sure what to say about that. I'm looking at a ViewPage in production right now that uses Page_Load to set some data on an old control we adapted for MVC. Regardless, either cramming the date ticks inline or using a helper is the better solution by a mile.
Stuart Branham
Maybe it just doesn't work on the MVC-flavored MasterPage (ViewMasterPage). I'll have to test that out later. Thanks Stuart.
tyndall
That's probably it. I forgot about us being on a master page! -1 for me. ;)
Stuart Branham
Something else weird. The <%=DateTime.Now%> inside an attribute did not work. Wonder if this is a MasterPage thing too. I had to use the code in the comment below, but will eventually write a helper so I can reuse it in other projects.
tyndall
<%= @"<link rel=""stylesheet"" type=""text/css"" href=""../../Content/css/expect.css?t=" + DateTime.Now.Ticks.ToString() + @""" />" %>
tyndall
Wow. Even when I do the engine complains about "using <% %> tags when modifying the controls collection. I imagine this is caused by the asp:ContentPlaceHolder. I can remove it, but then I can't use the CSS intellisense workaround mentioned here: http://stackoverflow.com/questions/524732/
tyndall
+2  A: 

You have declared cssLink as a local variable in Page_Load. As such, it will not be available to your page.

This should fix the issue for you:

<script runat="server">
    private string cssLoc;
    private string cssLink;

    void Page_Load(object sender, EventArgs e)
    {

        cssLoc = "../../Content/css/expect.css?t=" + DateTime.Now.Ticks.ToString();
        cssLink = String.Format(@"<link rel=""stylesheet"" type=""text/css"" href=""{0}"" />", cssLoc);
    }
</script>

<!DOCTYPE html>
<html>
<head id="Head1" runat="server">   
    <asp:ContentPlaceHolder ID="head" runat="server">
    <title></title>
    </asp:ContentPlaceHolder>    
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <%= cssLink %>
    <script type="text/javascript" src="../../Scripts/jquery.js"></script>
</head>

Edit: Aside from answering your direct question, I would recommend finding a more MVC-friendly solution (rather than putting code in your master page). For example, you could include the css location as ViewData["Stylesheet"] or use a different mechanism to update the css (I'm not up to date on the RC of MVC)

Richard Szalay
+1, good one. Note sure how I missed the local scoping. -1 cool point for me.
tyndall
+2  A: 
<head runat="server">
      <title>Some Title</title> -- WILL FIX YOUR ISSUE
      ...
      <%= Helper.CustomStyle() %>
      ...
</head>

This Helper.CustomStyle will have the logic inside that varies based on a DateTime.Now call as seen above.

A very good tutorial that will help you to understand the Custom Helpers can be found here: http://www.asp.net/learn/mvc/tutorial-09-cs.aspx

REMEMBER -- ASP.NET MVC does away with Page_Load type calls. It's a distinct design pattern!

Bill Konrad
Does fixing my `<title/>` this way break the ability for other Controllers to set the Title on pages?
tyndall
+2  A: 

Consider writing a helper to link that CSS file.

public static string DatedStylesheet(this HtmlHelper Html, string url, DateTime date)
{
    UrlHelper Url = new UrlHelper(new RequestContext(Html.ViewContext.HttpContext, Html.ViewContext.RouteData));
    string html = "<link type=\"text/css\" rel=\"stylesheet\" href=\"{0}?t={1}\"/>";

    return string.Format(html, Url.Content(url), date.Ticks.ToString());
}

<%= Html.DatedStylesheet("~/Content/css/expect.css", DateTime.Now);

On an unrelated note, does anyone know a cleaner way to do use UrlHelper outside of a view page?

Stuart Branham
This is cool. I like where you are heading with this. +1
tyndall