Stopping MVC ViewMasterPage from resolving CSS URLs
By default Master pages in .NET MVC2 placed like this /folderlevel1/folderlevel2/Site.master
accessed from the url domain.com/urllevel1/urllevel2/
will resolve the URL in this tag:
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
to
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
This becomes problematic in my multi-tennant MVC app. 开发者_开发百科And I want to stop this behaviour. I want the master page to leave the url alone.
You are probably having this issue because ASP.NET performs magic tricks when you specify the head
tag as a server side control like so:
<head runat="server">
These tricks include:
- resolving relative CSS paths
- populating title and meta tags from your view's @Page directive
If you don't want these tricks, simply remove the runat
attribute from the head
tag:
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html>
<html>
<head>
<link href="Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
...
</body>
</html>
you can use
<link href="<%=Url.Content("~/Content/Site.css")%>" rel="stylesheet" type="text/css" />
but that basically always translates to this:
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
so you might as well just use the latter.
Like mentioned on Kazi's best practices entry (http://weblogs.asp.net/rashid/archive/2009/04/03/asp-net-mvc-best-practices-part-2.aspx), ignore routing when accessing resources. To do this it's very simple and works well. Add the below to your AddRoutes function in Global.asax
_routes.IgnoreRoute("assets/{*pathInfo}");
...where "assets/" is your content folder (by default it's "Content")
oscar,
i'm sure there will be many similar answers to follow, but the standard way would be:
<link href="<%=Url.Content("~/Content/Site.css")%>" rel="stylesheet" type="text/css" />
I may have missed something subtle here of course :)
I suggest using an extension method for the HtmlHelper
to take care of this task for you.
using System.Web;
using System.Web.Mvc;
namespace MyApplicationNamepsace.Views
{
public static class HtmlExtensions
{
public static IHtmlString RelativeCssLink(this HtmlHelper helper, string fileNameAndRelativePath)
{
TagBuilder builder = new TagBuilder("link");
builder.Attributes.Add("rel", "stylesheet");
builder.Attributes.Add("type", "text/css");
builder.Attributes.Add("href", fileNameAndRelativePath);
IHtmlString output = new HtmlString(builder.ToString());
return output;
}
}
}
Then make sure you add the namespace to the web.config file in the views folder.
<system.web>
<pages>
<namespaces>
<add namespace="MyApplicationNamespace.Views"/>
</namespaces>
</pages>
</system.web>
Then use it in your masterpage.
<head runat="server">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<%: Html.RelativeCssLink("Content/Site.css") %>
</head>
精彩评论