2009-06-03 7 views
2

J'ai une application ASP.NET qui utilise des thèmes. Faisons semblant d'avoir un thème nommé "MySkin".ASP.NET - Thèmes et référence relative

J'ai une page qui est dans un sous-répertoire de mon application. Lorsque je référence une page qui utilise "MySkin", j'ai remarqué qu'ASP.NET restitue un élément de lien qui monte à la racine du site, puis descend dans le répertoire App_Themes. Voici un élément de liaison d'exemple, je trouve dans un rendu la page ASP.NET:

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

est-il une raison pour que l'élément de liaison rendu ne pas utiliser les éléments suivants à la place:

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

Est-ce un navigateur problème de compatibilité ou existe-t-il une autre raison?

La raison pour laquelle je demande est parce que je rends ma page ASP.NET en utilisant Server.Execute et en stockant le résultat dans un répertoire différent. Pour cette raison, je préférerais utiliser la deuxième façon de référencer le CSS de mon thème.

Merci!

Répondre

0

Selon la création intégrée PageThemeBuildProvider de classe interne, asp.net chemin relatif pour les fichiers CSS inclus dans le répertoire du thème

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

Pour surmonter votre problème, vous pouvez essayer d'utiliser balise de base:

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

La mauvaise chose à propos de l'utilisation de cette approche est que vos liens se casseront si l'URL de l'application est modifiée.

Pour minimiser l'impact tels le changement, vous pouvez utiliser html inclure en place de l'étiquette de base pour inclure un fichier contenant votre balise de base comme suit:

base.html contient:

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

cela pourrait être créé sur l'application commence la demande:

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

et ajouté en tant que contrôle littéral à votre 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 contient:

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

MISE À JOUR: Cela a été testé sous serveur de développement asp.net, si hébergé que l'application sous IIS le AppRoot ne sera pas résolu correctement. Pour obtenir les bonnes applications utilisez l'adresse absolue:

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