15

我想从诸如 Global.asax (HttpApplication)、HttpModule、HttpHandler 等非页面上下文中解析“~/whatever”,但只能找到特定于控件(和页面)的此类解析方法。

我认为应用程序应该有足够的知识能够将其映射到页面上下文之外。不?或者至少它对我来说是有意义的,它应该在其他情况下可以解决,无论应用程序根是什么已知的。

更新:原因是我在 web.configuration 文件中粘贴“~”路径,并希望从上述非控制场景中解决它们。

更新 2:我正在尝试将它们解析为网站根目录,例如 Control.Resolve(..) URL 行为,而不是文件系统路径。

4

6 回答 6

37

答案是: ASP.Net:在共享/静态函数中使用 System.Web.UI.Control.ResolveUrl()

string absoluteUrl = VirtualPathUtility.ToAbsolute("~/SomePage.aspx");
于 2010-04-07T03:18:51.463 回答
1

在 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;
    }
}
于 2013-02-18T11:07:26.197 回答
1

您可以通过HttpContext.Current直接访问对象来做到这一点:

var resolved = HttpContext.Current.Server.MapPath("~/whatever")

需要注意的一点是,HttpContext.Current它只会null在实际请求的上下文中不存在。例如,它在活动中不可用Application_Stop

于 2010-04-07T02:05:35.883 回答
0

尝试使用 System.AppDomain.BaseDirectory,而不是使用 MapPath。对于网站,这应该是您网站的根目录。然后执行 System.IO.Path.Combine 与您要传递给 MapPath 的任何内容,而不使用“~”。

于 2010-04-07T03:29:40.220 回答
0

我还没有调试过这个傻瓜,但由于在 Control 之外的 .NET Framework 中找不到 Resolve 方法,我把它作为手动解决方案扔在那里。

这对我来说确实适用于“~/whatever”。

/// <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;
}
于 2010-04-07T02:26:52.087 回答
0
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));
}
于 2010-04-07T03:09:33.680 回答