Как я могу решить ASP.NET «~» Пути приложений к корню веб-сайта без присутствующего контроля?
-
25-09-2019 - |
Вопрос
Я хочу решить «~ / что угодно» изнутри нестраничных контекстов, таких как Global.Asax (httpapplication), httpModule, httphandler и т. Д., Но можно найти только такие методы разрешения, характерные для управления (и страницы).
Я думаю, что приложение должно иметь достаточно знаний, чтобы иметь возможность сопоставить это вне контекста страницы. Нет? Или, по крайней мере, это имеет смысл для меня, оно должно быть разрешено в других обстоятельствах, где известен корень приложения.
Обновлять: Причина, когда я придерживаюсь «~» пути в файлах Web.Configuration, и хочу разрешить их из вышеупомянутых не контрольных сценариев.
Обновление 2: Я пытаюсь решить их на веб-сайт, такой как Control.Resolve (..) поведение URL, а не к пути файловой системы.
Решение
Вот ответ:ASP.NET: Использование System.Web.ui.control.resulleurl () в общей / статической функции
string absoluteUrl = VirtualPathUtility.ToAbsolute("~/SomePage.aspx");
Другие советы
Вы можете сделать это, доступа к HttpContext.Current
Объект напрямую:
var resolved = HttpContext.Current.Server.MapPath("~/whatever")
Один момент к примечанию в том, что HttpContext.Current
только будетnull
в контексте реального запроса. Это не доступно в Application_Stop
Событие, например.
В Global.Asax Добавьте следующее:
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;
}
}
Я не отладил эту присоску, но я бросаю его там в качестве ручного решения для отсутствия поиска метода разрешения в .NET Framework вне контроля.
Это работало на «~ / что угодно» для меня.
/// <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));
}
Вместо использования mappath попробуйте использовать system.appdomain.basedirectory. Для веб-сайта это должен быть корнем вашего сайта. Тогда сделайте System.io.O.Path.com, когда вы собирались перейти к MapPath без «~».