无法在虚拟目录中使用 MVC2 在 Site.Master 中正确引用 CSS

发布于 2024-09-26 01:42:56 字数 2287 浏览 4 评论 0原文

目前,我的 MVC 应用程序有一个 Site.Master 页面,直接从 VS2008 运行时效果非常好。它看起来像这样:

<%@ 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>

不幸的是,当在“虚拟目录”中的 IIS 6.0 服务器上使用时,CSS 引用无法加载并且页面无法正确呈现。 (通过虚拟目录,我的意思是 http://localhost/MyTestSite ,其中“MyTestSite”是在 IIS 中创建的虚拟目录安装 MVC 应用程序的服务器上的管理器。)

MVC 应用程序运行良好,并且由它生成的 HTML 加载正常,但服务器似乎无法找到引用的 CSS 和相关图像的位置。我觉得这很令人困惑,因为从 VS2008 运行时它似乎工作得很好。

确实找到了解决问题的方法,但我对结果并不完全满意:

<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") %> />

使用 Page.ResolveUrl() 对我来说感觉像是一种黑客行为,因为它破坏了在 VS2008 中编辑时呈现页面的拆分和/或设计视图。 (所有 CSS 标签都用绿色下划线表示“不存在”。)也就是说,当“运行”时,它在 IIS6 和 VS2008 中都呈现得很好。

有更好的方法来解决这个问题吗?

编辑:我的问题听起来像这里描述的问题:http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx -- 但我已经对 default.aspx.cs 文件进行了修复,如下所示。

   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);
   }

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);
   }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

故乡的云 2024-10-03 01:42:56
<link href="<%= Url.Content("~/Content/css/mystyle.css") %>"
        rel="stylesheet" type="text/css" />

编辑:

经过一番思考后,我意识到,当使用 VS 2008 时,您可能在“ASP.Net Development Server”下运行网站时使用调试模式,并且当您部署到 IIS 时,您可能已经发布了发布模式下的代码。

如果是这种情况,那么您可以尝试以下操作:

<% #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 %>

现在,当您在 Visual Studio 2008 中运行时,您的 CSS 代码完成工具将可以正常工作,并且可以在虚拟目录中运行您的网站(作为发布版本)。

<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.

呢古 2024-10-03 01:42:56

John Hartsock 正在访问 某事,但他试图执行的预处理器命令在设计模式下无法按预期工作(我认为它实际上试图同时执行这两件事)。您可以尝试检查 .NET Site 属性,该属性可用于测试您是否在设计模式下运行(在发布配置中,Site 属性并不总是已填充,因此您还必须检查它是否不为空)。

此外,Visual Studio 设计查看器不知道域和虚拟应用程序路径,因此在设计器中您可以使用 / 指向应用程序根目录。

<% 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"/>
<% } %>

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"/>
<% } %>
じ违心 2024-10-03 01:42:56

恐怕没有优雅的方法来做到这一点。您可以执行以下可怕的黑客行为来欺骗设计器:

<% 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") %>" />

就我个人而言,我从不使用设计器,也永远不会在我的代码中执行类似的操作,但如果您确实需要这种设计视图,那么它可能是一个解决方案。

我的意思是你正在一个 ASP.NET MVC 项目中工作,你应该操作 html,为什么关心设计视图?看看为了让设计视图发挥作用你应该支付的价格,它太贵了。在您最喜欢的浏览器中按 CTRL+F5 来查看您的工作结果比一直在代码和设计视图之间切换要更快。

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.

梦里的微风 2024-10-03 01:42:56

也许这是显而易见的,或者我错过了一些东西,但这看起来像是路径问题。您正在使用相对路径 (../../)。我相信当您在 Visual Studio 中运行某些内容时,应用程序是根路径(即项目主目录中的 default.aspx 将为 localhost:port/default.aspx )。如果任何页面中的相对路径出现太多目录(即 ../ 太多次),它将被忽略并从网站的根目录获取(在本例中为 localhost:端口/)。例如,如果您的文件夹结构是这样的:

  • AppRoot
    • 样式(文件夹)
    • 内容(文件夹)
    • 其他文件(文件夹)
      • myfile.aspx
    • 默认.aspx

您可以使用 ../content/myfile.aspx 访问 content 文件夹,或者,即使您不应该这样做,也可以使用 ../../content/ 这仅在 AppRoot 与域根相同时有效(即 localhost:port/content/domain.com/content/ 是同一文件夹)。
但是,如果您现在将这些文件放在 Web 服务器上的另一个(虚拟)文件夹中(即 domain.com/virtual == new AppRoot),../../contentdomain.com/virtual/otherfiles/myfile.aspx 中的 code> 将引用 domain.com/content/,这是不正确的。

我希望这有帮助。

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.

一口甜 2024-10-03 01:42:56

刚刚测试了以下内容,以确保它能够解决您的两个问题(启用设计视图并正确解决)。希望它对你有用

<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" />

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" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文