`Page.ResolveUrl()` 存在已知缺陷:
public static string ResolveUrl(string relativeUrl)
{
if (relativeUrl == null) throw new ArgumentNullException(nameof(relativeUrl));
if (relativeUrl.Length == 0 || relativeUrl[0] == '/' || relativeUrl[0] == '\\')
return relativeUrl;
int idxOfScheme = relativeUrl.IndexOf("://", StringComparison.Ordinal);
if (idxOfScheme != -1)
{
int idxOfQM = relativeUrl.IndexOf('?');
if (idxOfQM == -1 || idxOfQM > idxOfScheme)
return relativeUrl; // 真正的絕對網址
}
var sb = new StringBuilder();
sb.Append(HttpRuntime.AppDomainAppVirtualPath);
if (sb.Length == 0 || sb[sb.Length - 1] != '/') sb.Append('/');
bool foundQM = false, foundSlash = false;
if (relativeUrl.Length > 1 && relativeUrl[0] == '~' && (relativeUrl[1] == '/' || relativeUrl[1] == '\\'))
{
relativeUrl = relativeUrl.Substring(2);
foundSlash = true;
}
foreach (char c in relativeUrl)
{
if (!foundQM)
{
if (c == '?') foundQM = true;
else if (c == '/' || c == '\\')
{
if (foundSlash) continue;
sb.Append('/');
foundSlash = true;
continue;
}
else if (foundSlash) foundSlash = false;
}
sb.Append(c);
}
return sb.ToString();
}
10 萬次迴圈呼叫,本方案平均耗時為原 `Page.ResolveUrl()` 的 1/2.7,顯著降低高併發下 CPU 開銷。