ASP.NET - темы и относительные ссылки - PullRequest
2 голосов
/ 03 июня 2009

У меня есть приложение 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" />

Это проблема совместимости браузера или есть другая причина?

Причина, по которой я спрашиваю, заключается в том, что я отрисовываю свою страницу ASP.NET с использованием Server.Execute и сохраняю результат в другом каталоге. Из-за этого я предпочел бы использовать второй способ для ссылки на css моей темы.

Спасибо!

1 Ответ

0 голосов
/ 17 мая 2010

Согласно встроенному внутреннему классу 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 содержит:

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

сохраненный.html содержит:

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

UPDATE: Это было проверено на сервере разработки asp.net, если AppRoot, размещенный как приложение под IIS, не будет правильно разрешен. Чтобы получить правильные приложения, используйте абсолютный 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));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...