Why do I get an HttpException from VirtualPathUtility ToAbsolute with some paths?

拜拜、爱过 提交于 2019-12-10 16:24:27

问题


I'm trying to use VirtualPathUtility.ToAbsolute to resolve app-relative paths, such as ~/MyPage.aspx, to application-absolute paths, such as /MySite/MyApp/MyPage.aspx. However, with some paths, I receive an HttpException saying that my path is "not a valid virtual path". Examples:

// This works:
var abs1 = VirtualPathUtility.ToAbsolute("~/MyPage.aspx#anchor");

// This errors:
var abs2 = VirtualPathUtility.ToAbsolute("~/MyPage.aspx?key=value");

What's going on?


回答1:


Because you're using .NET 3.5, you're using the 2.0 System.Web assembly, which has the defect that ? is considered an illegal path character by this method. This is mentioned in the community comments on the version-specific MSDN page.

By disassembling, it can be seen that the call ends up in the (internal) VirtualPath.Create, which has:

  else if (VirtualPath.ContainsIllegalVirtualPathChars(virtualPath))
  {
    throw new HttpException(System.Web.SR.GetString("Invalid_vpath", new object[1]
    {
      (object) virtualPath
    }));
  }

which references

private static char[] s_illegalVirtualPathChars = new char[4]
{
  ':',
  '?',
  '*',
  char.MinValue
};

Some of these can reasonably be regarded as bad characters for a path, but ? shouldn't really be so rejected.

Disassembly of the 4.0 System.Web shows that VirtualPath.Create has been rewritten to be more discerning.

This web.archive capture of a now-defunct blogs.msdn post shows one of the earliest mentions of this problem. The MS employee responds:

Sunday, February 26, 2006 11:49 PM by DmitryR Exception on ~/path?qs is a bug that I'll need to fix...

The easiest fix is to save/restore query string in ResolveAppRelativeLinkToUrl around the call to VirtualPathUtility.ToAbsolute.

A workaround is to use fully qualified UTLs instead of "~/...".

Thanks,

Dmitry

where ResolveAppRelativeLinkToUrl refers to the reporter's code's method name.

Another workaround would be to replace ? with a safe token before the call to VirtualPathUtility.ToAbsolute, and reverse the replacement afterwards:

public static string SafeToAbsolute(string path)
{
    var madeSafe = path.Replace("?", "UNLIKELY_TOKEN");
    var absolute = VirtualPathUtility.ToAbsolute(madeSafe);
    var restored = absolute.Replace("UNLIKELY_TOKEN", "?");
    return restored;
}

choosing a suitably unlikely token for your application.



来源:https://stackoverflow.com/questions/13360419/why-do-i-get-an-httpexception-from-virtualpathutility-toabsolute-with-some-paths

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!