Brondahl Brondahl - 6 months ago 21
CSS Question

Constructed CSS link in Razor view

I have a lot of copies of this in my codebase:

@if (Context.IsDebuggingEnabled)
{
<link rel='stylesheet' href='~/Styles/FrontEnd.css' type='text/css'
}
else
{
<link rel='stylesheet' href='/public/css/FrontEnd-min.css' type='text/css' />
}


And this was irritating me, so I wanted to pull that if and the duplication into a helper method, which I did:

public static MvcHtmlString IncludeDebugAwareStylesheet(this HtmlHelper htmlHelper, string debugFileName, string liveFileName)
{
var styleSheetWrapperFormat = "<link rel='stylesheet' href='{0}' type='text/css' />";
var debugInclude = string.Format(styleSheetWrapperFormat, debugFileName);
var liveInclude = string.Format(styleSheetWrapperFormat, liveFileName);
var isDebug = htmlHelper.ViewContext.HttpContext.IsDebuggingEnabled;
return new MvcHtmlString(isDebug ? debugInclude : liveInclude );
}


But now the CSS files aren't being recognised.
As far as I can tell, in the original, the
~
is getting removed, but in my new code, it isn't?

Why is this? Do I need to tell Razor to "Process" the URL in some manner?

Answer

You need to use UrlHelper.GenerateContentUrl to resolve the project-relative reference.

Try:

public static MvcHtmlString IncludeDebugAwareStylesheet(this HtmlHelper htmlHelper, string debugFileName, string liveFileName)
{
    var styleSheetWrapperFormat = "<link rel='stylesheet' href='{0}' type='text/css' />";
    var debugInclude = string.Format(styleSheetWrapperFormat, UrlHelper.GenerateContentUrl(debugFileName, htmlHelper.ViewContext.HttpContext));
    var liveInclude = string.Format(styleSheetWrapperFormat, UrlHelper.GenerateContentUrl(liveFileName, htmlHelper.ViewContext.HttpContext));
    var isDebug = htmlHelper.ViewContext.HttpContext.IsDebuggingEnabled;
    return new MvcHtmlString(isDebug ? debugInclude : liveInclude );
}

This is because ~ means "project-root" in ASP.Net/MVC. In your .cshtml files the Razor view engine is automatically compiling those references into a the correct relative url, but your HtmlHelper extension is currently just putting the string in as-is, rather than resolving the reference first.

Comments