ASP.NET - 主题和相对引用

发布于 2024-07-22 04:40:19 字数 587 浏览 6 评论 0原文

我有一个使用主题的 ASP.NET 应用程序。 假设我有一个名为“MySkin”的主题。

我的应用程序的子目录中有一个页面。 当我引用使用“MySkin”的页面时,我注意到 ASP.NET 呈现一个链接元素,该元素向上走到站点的根目录,然后向下进入 App_Themes 目录。 下面是我在呈现的 ASP.NET 页面中找到的示例链接元素:

<link href="../../App_Themes/MySkin/theme.css" type="text/css" rel="stylesheet" />

呈现的链接元素不使用以下内容是否有原因:

<link href="/App_Themes/MySkin/theme.css" type="text/css" rel="stylesheet" />

这是浏览器兼容性问题还是还有其他原因?

我问的原因是因为我正在使用 Server.Execute 渲染 ASP.NET 页面并将结果存储在不同的目录中。 因此,我更愿意使用第二种方式来引用我的主题的 css。

谢谢你!

I have an ASP.NET application that uses themes. Let's pretend I have a theme named "MySkin".

I have a page that is in a sub-directory of my application. When I reference a page that uses "MySkin", I noticed that ASP.NET renders a link element that walks up to the root of the site and then down into the App_Themes directory. Here is an example link element I found in a rendered ASP.NET page:

<link href="../../App_Themes/MySkin/theme.css" type="text/css" rel="stylesheet" />

Is there a reason that the rendered link element does not use the following instead:

<link href="/App_Themes/MySkin/theme.css" type="text/css" rel="stylesheet" />

Is this a browser compatibility issue or is there another reason?

The reason I am asking is because I am rendering my ASP.NET page using Server.Execute and storing the result in a different directory. Because of this, I would prefer to use the second way to reference my theme's css.

Thank you!

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

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

发布评论

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

评论(1

揽清风入怀 2024-07-29 04:40:19

根据内置的内部类PageThemeBuildProvider,asp.net为主题目录中包含的css文件创建相对路径

internal void AddCssFile(VirtualPath virtualPath)
{
    if (this._cssFileList == null)
    {
        this._cssFileList = new ArrayList();
    }
    this._cssFileList.Add(virtualPath.AppRelativeVirtualPathString);
}

要解决您的问题,您可以尝试使用基本标签:

//Add base tag which specifies a base URL for all relative URLs on a page
System.Web.UI.HtmlControls.HtmlGenericControl g = new System.Web.UI.HtmlControls.HtmlGenericControl("base");
//Get app root url
string AppRoot = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, "");
g.Attributes.Add("href",AppRoot);
Page.Header.Controls.AddAt(0,g);

使用这种方法的坏处是,如果应用程序,您的链接将中断url 发生变化。

为了最大限度地减少此类更改的影响,您可以使用 html include 代替基本标记来包含包含基本标记的文件,如下所示:

base.html contains:

<base href="http://localhost:50897"></base>

这可以在应用程序开始请求时创建:

bool writeBase = true;
        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            if (writeBase)
            {
                writeBase = false;
                //Save it to a location that you can easily reference from saved html pages.                
                string path = HttpContext.Current.Server.MapPath("~/App_Data/base.html");
                using (System.IO.TextWriter w = new System.IO.StreamWriter(path, false))
                {
                    w.Write(string.Format("<base href=\"{0}\"></base>", HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.PathAndQuery, "")));
                    w.Close();
                }
            }            
        }

并作为文字控件添加到您的aspx :

//the path here depends on where you are saving executed pages.
System.Web.UI.LiteralControl l = new LiteralControl("<!--#include virtual=\"base.html\" -->");
Page.Header.Controls.AddAt(0,l);

saved.html 包含:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--#include virtual="base.html" -->
...
</head>
 .... 
</html>

更新:
这是在 asp.net 开发服务器下测试的,如果在 IIS 下作为应用程序托管,则 AppRoot 将无法正确解析。 要获取正确的应用程序绝对 url,请使用:

/// <summary>
/// Get Applications Absolute Url with a trailing slash appended.
/// </summary>
public static string GetApplicationAbsoluteUrl(HttpRequest Request)
{   
return VirtualPathUtility.AppendTrailingSlash(string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Request.ApplicationPath));
}

According to the built-in internal class PageThemeBuildProvider, asp.net create relative path for css files included in the theme directory

internal void AddCssFile(VirtualPath virtualPath)
{
    if (this._cssFileList == null)
    {
        this._cssFileList = new ArrayList();
    }
    this._cssFileList.Add(virtualPath.AppRelativeVirtualPathString);
}

To overcome your problem you may try using base tag:

//Add base tag which specifies a base URL for all relative URLs on a page
System.Web.UI.HtmlControls.HtmlGenericControl g = new System.Web.UI.HtmlControls.HtmlGenericControl("base");
//Get app root url
string AppRoot = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, "");
g.Attributes.Add("href",AppRoot);
Page.Header.Controls.AddAt(0,g);

The bad thing about using this approach is your links will break if the application url gets changed.

To minimize such change impact, you may use html include in place of the base tag to include a file containing your base tag as follows:

base.html contains:

<base href="http://localhost:50897"></base>

this could be created on application begin request:

bool writeBase = true;
        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            if (writeBase)
            {
                writeBase = false;
                //Save it to a location that you can easily reference from saved html pages.                
                string path = HttpContext.Current.Server.MapPath("~/App_Data/base.html");
                using (System.IO.TextWriter w = new System.IO.StreamWriter(path, false))
                {
                    w.Write(string.Format("<base href=\"{0}\"></base>", HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.PathAndQuery, "")));
                    w.Close();
                }
            }            
        }

and added as a literal control to your aspx :

//the path here depends on where you are saving executed pages.
System.Web.UI.LiteralControl l = new LiteralControl("<!--#include virtual=\"base.html\" -->");
Page.Header.Controls.AddAt(0,l);

saved.html contains:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--#include virtual="base.html" -->
...
</head>
 .... 
</html>

UPDATE:
This was tested under asp.net development server, if hosted as application under IIS the AppRoot will not be resolved correctly. To get the correct applications absolute url use:

/// <summary>
/// Get Applications Absolute Url with a trailing slash appended.
/// </summary>
public static string GetApplicationAbsoluteUrl(HttpRequest Request)
{   
return VirtualPathUtility.AppendTrailingSlash(string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Request.ApplicationPath));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文