Come posso risolvere ASP.NET “~” percorsi app alla radice sito senza un controllo essere presenti?
-
25-09-2019 - |
Domanda
Voglio Resolve "~ / qualunque cosa" da dentro non Pagina contesti come Global.asax (HttpApplication), HttpModule, HttpHandler, ecc, ma non può che trovare tali metodi risoluzione specifica ai controlli (e la pagina).
Credo che l'applicazione dovrebbe avere conoscenze sufficienti per essere in grado di mappare questo al di fuori del contesto di pagina. No? O almeno ha senso per me dovrebbe essere risolvibile in altre circostanze, laddove la radice applicazione è nota.
Aggiorna :. La ragione è che sto attaccando "~" percorsi nei file web.configuration, e vuole risolverli dai summenzionati scenari non di controllo
Aggiornamento 2:. sto cercando di risolverli alla radice sito web come Control.Resolve (..) URL comportamento, non a un percorso del file system
Soluzione
Ecco la risposta: ASP.Net: using System .Web.UI.Control.ResolveUrl () in una funzione condivisa / static
string absoluteUrl = VirtualPathUtility.ToAbsolute("~/SomePage.aspx");
Altri suggerimenti
È possibile farlo accedendo direttamente l'oggetto HttpContext.Current
:
var resolved = HttpContext.Current.Server.MapPath("~/whatever")
Un punto da notare è che, HttpContext.Current
è solo andare a essere non null
nel contesto di una richiesta effettiva. Non è disponibile in caso Application_Stop
, per esempio.
In Global.asax aggiungere quanto segue:
private static string ServerPath { get; set; }
protected void Application_BeginRequest(Object sender, EventArgs e)
{
ServerPath = BaseSiteUrl;
}
protected static string BaseSiteUrl
{
get
{
var context = HttpContext.Current;
if (context.Request.ApplicationPath != null)
{
var baseUrl = context.Request.Url.Scheme + "://" + context.Request.Url.Authority + context.Request.ApplicationPath.TrimEnd('/') + '/';
return baseUrl;
}
return string.Empty;
}
}
Non ho il debug questa ventosa ma sto gettandolo nostro lì come una soluzione manuale per mancanza di trovare un metodo Resolve nella parte esterna .NET Framework di controllo.
Questo ha funzionato su un "~ / qualunque cosa" per me.
/// <summary>
/// Try to resolve a web path to the current website, including the special "~/" app path.
/// This method be used outside the context of a Control (aka Page).
/// </summary>
/// <param name="strWebpath">The path to try to resolve.</param>
/// <param name="strResultUrl">The stringified resolved url (upon success).</param>
/// <returns>true if resolution was successful in which case the out param contains a valid url, otherwise false</returns>
/// <remarks>
/// If a valid URL is given the same will be returned as a successful resolution.
/// </remarks>
///
static public bool TryResolveUrl(string strWebpath, out string strResultUrl) {
Uri uriMade = null;
Uri baseRequestUri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority));
// Resolve "~" to app root;
// and create http://currentRequest.com/webroot/formerlyTildeStuff
if (strWebpath.StartsWith("~")) {
string strWebrootRelativePath = string.Format("{0}{1}",
HttpContext.Current.Request.ApplicationPath,
strWebpath.Substring(1));
if (Uri.TryCreate(baseRequestUri, strWebrootRelativePath, out uriMade)) {
strResultUrl = uriMade.ToString();
return true;
}
}
// or, maybe turn given "/stuff" into http://currentRequest.com/stuff
if (Uri.TryCreate(baseRequestUri, strWebpath, out uriMade)) {
strResultUrl = uriMade.ToString();
return true;
}
// or, maybe leave given valid "http://something.com/whatever" as itself
if (Uri.TryCreate(strWebpath, UriKind.RelativeOrAbsolute, out uriMade)) {
strResultUrl = uriMade.ToString();
return true;
}
// otherwise, fail elegantly by returning given path unaltered.
strResultUrl = strWebpath;
return false;
}
public static string ResolveUrl(string url)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentException("url", "url can not be null or empty");
}
if (url[0] != '~')
{
return url;
}
string applicationPath = HttpContext.Current.Request.ApplicationPath;
if (url.Length == 1)
{
return applicationPath;
}
int startIndex = 1;
string str2 = (applicationPath.Length > 1) ? "/" : string.Empty;
if ((url[1] == '/') || (url[1] == '\\'))
{
startIndex = 2;
}
return (applicationPath + str2 + url.Substring(startIndex));
}
Invece di usare MapPath, provare a utilizzare System.AppDomain.BaseDirectory. Per un sito web, questo dovrebbe essere la radice del tuo sito web. Poi fare uno System.IO.Path.Combine con qualsiasi cosa si stavano per passare al MapPath senza il "~".