ASP.NET を使用した私の個人的な経験と、インターネットでの検索に基づいています。 Page の ResolveUrl メソッドがいくつかの深刻な問題を引き起こしていることがわかりました。
最も一般的な問題は、ページまたはコントロールのスコープ外で使用できないことです。
その他の問題はすべてバグです。たとえば、指定された一部の URL を正しく処理できません。たとえば、Page.ResolveUrl("~/test.aspx?param=http://www.test.com") を試してください。結果は、入力した文字列と同じであり、変更はありません。 Reflector を使用して asp.net コードを表示すると、相対 URL を絶対 URL に変換するメカニズムは、まず文字列内で「://」を検索し、見つかった場合はそれを直接返すことがわかりました。したがって、パラメータを :// で渡せば、クエリ文字列は問題ありません。クエリ文字列パラメータは URL エンコードする必要があることは誰もが知っていますが、そうでない場合でも、URL では受け入れられるはずです。真剣に、ブラウザを確認してください。
オンラインでは、VirtualPathUtility.ToAbsolute を使用することをお勧めします。これは、URL をクエリ文字列として渡す場合には非常に便利であり、そうでない場合は例外がスローされます。絶対 URL の場合も例外がスローされます。
そこで、最終的な解決策を探すことにしました。
まず、ページ コンテキストを使用せずに、アプリケーションの実行中に仮想パスを提供する適切な変数を探します。
HttpRuntime.AppDomainAppVirtualPath を使用しました。タイマー コールバックなど、どこでも使用できます。パスの末尾にスラッシュがありません。ASP.NET では特異的にスラッシュが削除されていますが、修正できます :-)
次に、元の ResolveUrl コードを使用していくつかのテストを行い、それを AppVirtualPath に置き換える方法を見つけました。
1. URL がスラッシュ (/ または ) で始まる場合、URL は変更されません。
2. URL が 〜/ で始まる場合、AppVirtualPath に置き換えられます。
3. URLが絶対URLの場合は変更されません。
4. その他の場合 (スラッシュの代わりに 〜 で始まる場合でも)、URL は AppVirtualPath に追加されます。
5. URL を変更するたびに、スラッシュも修正されます。二重スラッシュを削除し、 を / に置き換えます。
コード:
コード
パブリック静的文字列 ResolveUrl(文字列相対 URL)
{
if (relativeUrl == null) throw new ArgumentNullException("relativeUrl");
if (relativeUrl.Length == 0 ||relativeUrl[0] == '/' ||
relativeUrl[0] == '\')relativeUrl を返します。
int idxOfScheme =
relativeUrl.IndexOf(@"://", StringComparison.Ordinal);
if (idxOfScheme != -1)
{
int idxOfQM =relativeUrl.IndexOf('?');
if (idxOfQM == -1 || idxOfQM > idxOfScheme) 相対 URL を返します。
}
StringBuilder sbUrl = new StringBuilder();
sbUrl.Append(HttpRuntime.AppDomainAppVirtualPath);
if (sbUrl.Length == 0 || sbUrl[sbUrl.Length - 1] != '/') sbUrl.Append('/');
// クエリ文字列がすでに見つかりました。触らないでください。
ブール値が見つかりましたQM = false;
bool foundSlash; // 最新の文字はスラッシュでしたか?
if (relativeUrl.Length > 1
&& 相対 URL[0] == '~'
&& (relativeUrl[1] == '/' ||relativeUrl[1] == '\'))
{
相対URL = 相対URL.Substring(2);
見つかったスラッシュ = true;
}
それ以外の場合はスラッシュ = false; が見つかりました。
foreach (relativeUrl の char c)
{
if (!foundQM)
{
if (c == '?') foundQM = true;
それ以外
{
if (c == '/' || c == '\')
{
if (foundSlash) 続行;
それ以外
{
sbUrl.Append('/');
見つかったスラッシュ = true;
続く;
}
}
else if (foundSlash) foundSlash = false;
}
}
sbUrl.Append(c);
}
sbUrl.ToString() を返します。
}
コードを完成させ、元の ResolveUrl テストを何度も比較した後、パフォーマンスのテストを開始しました...ほとんどの場合、コードは元の ResolveUrl より 2.7 倍高速に実行されました。また、ループ内でテストし、さまざまな URL でコードを 100,000 回実行しました。
参考原文:http: //www.codeproject.com/KB/aspnet/resolveurl.aspx
著者:Zhu Qilin 出典:http: //zhuqil.cnblogs.com
この記事の著作権は著者に帰属しており、転載は歓迎します。ただし、この記述は著者の承諾なしに保持し、記事ページのわかりやすい位置に原文へのリンクを掲載する必要があります。法的責任を追及する権利は留保されます。