Puis-je accéder au nom du répertoire virtuel dans Global.asax.cs?
-
18-09-2019 - |
Question
La HttpContext.Current.Request.ApplicationPath
propriété représente le répertoire virtuel dans IIS ou WebDev.WebServer.
HttpContext.Current.Request.ApplicationPath evaluates to "/virtualdirectory"
Il peut être utilisé conjointement avec VirtualPathUtility
pour faire une racine de chemin relatif:
VirtualPathUtility.ToAbsolute("~/images/cat.jpg",
HttpContext.Current.Request.ApplicationPath)
// (this evaluates to "/virtualdirectory/images/cat.jpg")
Dans IIS6 et WebDev.WebServer l'objet Request est disponible en global.asax.cs
, mais IIS7 se plaint qu'il est «non disponible dans le contexte actuel. Par conséquent, la deuxième ligne de code ci-dessus fonctionne, mais pas dans IIS7.
Le problème est que je dois accéder au nom de directroy virtuel dans global.asax.cs
. J'ai besoin pour construire des chemins qui sont utilisés dans CSS créé dynamiquement. Y at-il un autre moyen d'accéder à cette valeur?
Modifier Ceci est l'erreur que vous obtenez dans IIS 7 pour appeler HttpContext.Current.Request
dans Global.asax.cs sous Application_Start:
HttpException (0x80004005): Request is not available in this context]
System.Web.HttpContext.get_Request() +8789264
La solution
Enfin trouvé la réponse simple!
HttpRuntime.AppDomainAppVirtualPath
Disponible immédiatement pendant Application_Start
est de la forme /myapplication
y compris le préfixe /
.
Autres conseils
Peut-on utiliser ResolveUrl ( "~ / images / cat.jpg") pour construire votre chemin?
Modifier ResolveUrl est une méthode de contrôle, non seulement la classe Page, vous pouvez le faire de cette façon plutôt que (peu laid peut-être):
System.Web.UI.Control c = new Control();
String s = c.ResolveUrl(@"~/images/cat.jpg");
Hmmm ... Je ne savais pas du changement IIS7. Je me demande si ce ne serait pas plus simple de reporter cette opération jusqu'à ce que vous Vous a obtenu une page. Par exemple, vous pouvez essayer de mettre quelque chose « une seule fois » dans Application_BeginRequest
ou Session_Start
?
Or (complètement non testé) pour un crochet d'auto-désabonnement:
public override void Init() {
base.Init();
EventHandler handler = null;
handler = delegate {
// do stuff, once only
this.BeginRequest -= handler;
};
this.BeginRequest += handler;
}
L'astuce est de le faire une seule fois (si plusieurs demandes arrivent à la fois); peut-être un cteur statique? Par exemple, je pense que cela déclenche une seule fois, et seulement quand il y a une page disponible dans le contexte:
static class DelayedLoader {
static DelayedLoader() {
string s = VirtualPathUtility.ToAbsolute("~/images/cat.jpg",
HttpContext.Current.Request.ApplicationPath);
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Init() { }
}
public override void Init() {
base.Init();
EventHandler handler = null;
handler = delegate {
DelayedLoader.Init();
this.BeginRequest -= handler;
};
this.BeginRequest += handler;
}
Ceci est le meilleur que je suis venu avec: Application_BeginRequest (par marque)
J'utilise asax si rarement que j'avais oublié temporairement vous différents événements avec elle. Jusqu'à présent, j'avais crée les sprites CSS dans Application_Start
. Se déplacer à BeginRequest était le meilleur que je pouvais trouver.
Un chèque booléenne pour chaque demande est négligeable, mais serait bien s'il y a une autre façon.
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
protected void Application_BeginRequest()
{
if (!_initialized)
{
lock (thisLock)
{
_initialized = true;
GenerateCSSSprites();
}
}
}
J'ai eu ce problème aussi lors du passage à IIS7 mais j'ai pu factoriser la nécessité pour la demande. Quel est ce que ce gars suggère également et fournit une solution de contournement si vous ne pouvez pas.