Unable to reference CSS properly in Site.Master with MVC2 in a Virtual Directory

匿名 (未验证) 提交于 2019-12-03 00:52:01

问题:

Currently, I have a Site.Master page for my MVC app that renders great when run directly from VS2008. It looks like this:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>   <meta http-equiv="content-type" content="text/html; charset=utf-8" />   <link rel="stylesheet" type="text/css" href="../../Content/css/layout1_setup.css" />   <link rel="stylesheet" type="text/css" href="../../Content/css/layout1_text.css" />   <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>   </head> 

Unfortunately, when used on my IIS 6.0 server in a "Virtual Directory", the CSS reference fails to load and the page fails to render properly. (By virtual directory, I mean something like http://localhost/MyTestSite where "MyTestSite" is the Virtual Directory created in IIS Manager on the server where the MVC app is installed.)

The MVC app runs fine and the HTML produced from it loads normally, but the server seems to be unable to find the location of the CSS and related images referenced. I find this baffling since it seems to work just fine when run from VS2008.

I did find a workaround to my issue, but I'm not exactly satisfied with the results:

<link rel="stylesheet" type="text/css" href=<%= Page.ResolveUrl(@"~/Content/css/layout1_setup.css") %> /> <link rel="stylesheet" type="text/css" href=<%= Page.ResolveUrl(@"~/Content/css/layout1_text.css") %> /> 

Using Page.ResolveUrl() feels like a hack to me as it breaks the rendering of the Split and/or Design view of page when editing in VS2008. (And all CSS tags are underlined in green as "not existing".) That said, it renders just fine in both IIS6 and VS2008 when "running".

Is there a better way to fix this problem?

EDIT: My problem sounds like the issue described here: http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx -- But I already have the fix for the default.aspx.cs file implemented as shown below.

   public void Page_Load(object sender, System.EventArgs e)    {         string originalPath = Request.Path;         HttpContext.Current.RewritePath(Request.ApplicationPath, false);  // Setting "false" on the above line is supposed to fix my issue, but it doesn't.         IHttpHandler httpHandler = new MvcHttpHandler();         httpHandler.ProcessRequest(HttpContext.Current);         HttpContext.Current.RewritePath(originalPath, false);    } 

回答1:

John Hartsock is on to something, but the preprocessor commands he is trying to execute does not work as expected in design mode (I think it actually tries to do both). You can instead try to check against a .NET Site property that is available to test if you run in design mode or not (in release configuration, the Site property is not always populated, so you also have to check if it is not null).

Also Visual Studio design viewer does not know of domain and virtual app path, so in the designer you can use / to point to app root.

<% if (Site != null && Site.DesignMode) { %>  <link href="/Content/css/layout1_setup.css" rel="stylesheet"/> <% } else { %>  <link href="<%= Url.Content("~/Content/css/layout1_setup.css") %>" rel="stylesheet"/> <% } %> 


回答2:

<link href="<%= Url.Content("~/Content/css/mystyle.css") %>"         rel="stylesheet" type="text/css" /> 

Edited:

After giving this some thought I relized that when using the VS 2008 you are probably using debug mode when running the website under "ASP.Net Development Server" And when you deploy to IIS you have probably published the code in Release Mode.

If this is the case then you can try the following:

<% #if DEBUG %>    <link rel="stylesheet" type="text/css" href="../../Content/css/layout1_setup.css" />    <link rel="stylesheet" type="text/css" href="../../Content/css/layout1_text.css" />  <% #else %>    <link rel="stylesheet" type="text/css" href="<%= Url.Content("~/Content/css/layout1_setup.css") %>" />    <link rel="stylesheet" type="text/css" href="<%= Url.Content("~/Content/css/layout1_text.css") %>" />  <% #endif %> 

Now with this when you run in Visual Studio 2008 your code completion tools for CSS will work as well as running your website (as a Release version) inside a virtual directory.



回答3:

I am afraid there's no elegant way of doing this. You could perform the following horrible hack to cheat the designer:

<% if (false) { %> <!-- That's just to cheat the designer, it will never render at runtime --> <link rel="stylesheet" type="text/css" href="../../Content/css/layout1_setup.css" /> <link rel="stylesheet" type="text/css" href="../../Content/css/layout1_text.css" /> <% } %> <link rel="stylesheet" type="text/css" href="<%= Url.Content("~/Content/css/layout1_setup.css") %>" /> <link rel="stylesheet" type="text/css" href="<%= Url.Content("~/Content/css/layout1_text.css") %>" /> 

Personally I never use the designer and would never do something like this in my code but if you really need to have this design view then it could be a solution.

I mean you are working in an ASP.NET MVC project, you should be manipulating html, why care about the design view? Look at the price you should pay just to get the design view working, it's too expensive. It's faster to hit CTRL+F5 in your favorite browser to see the result of your efforts than switching all the time between code and design view.



回答4:

Maybe this is obvious or I've missed something but this looks like a path issue. You are using relative paths (../../). I believe when you run something in Visual Studio, the application is the root path (ie. default.aspx in your project's main directory would be localhost:port/default.aspx). If a relative path in any page goes up too many directories (ie ../ too many times), it will be ignored and taken from the root of the website (in this case localhost:port/). For example, if your folder structure is like this:

  • AppRoot
    • styles (folder)
    • content (folder)
    • otherfiles (folder)
      • myfile.aspx
    • default.aspx

You can access the content folder from myfile.aspx by using ../content/ or, even though you shouldn't do this, by using ../../content/ This only works if AppRoot is the same as the domain root (ie. localhost:port/content/ and domain.com/content/ are the same folder).
However, if you put those files in another (virtual) folder on your web server (ie. domain.com/virtual == new AppRoot) now ../../content from domain.com/virtual/otherfiles/myfile.aspx will be referring to domain.com/content/, which is incorrect.

I hope this helps.



回答5:

Just tested the following to make sure it would solve both your problems (enabling design view & resolve properly). Hope it works for you

<link rel="stylesheet" type="text/css" href="~/Content/css/layout1_setup.css" runat="server" /> <link rel="stylesheet" type="text/css" href="~/Content/css/layout1_text.css" runat="server" /> 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!