ASP.NET을 사용한 개인적인 경험과 인터넷 검색을 바탕으로 작성되었습니다. 저는 Page의 ResolveUrl 메서드가 몇 가지 심각한 문제를 가져온다는 사실을 발견했습니다.
가장 일반적인 문제는 페이지나 컨트롤의 범위 밖에서 사용할 수 없다는 것입니다.
다른 모든 문제는 버그입니다. 예를 들어, 귀하가 제공한 일부 URL을 올바르게 처리할 수 없습니다. 예를 들어 Page.ResolveUrl("~/test.aspx?param=http://www.test.com")을 시도해 보세요. 결과는 변경 사항 없이 입력한 문자열과 동일합니다. Reflector를 사용하여 asp.net 코드를 보면 상대 URL을 절대 URL로 변환하는 메커니즘이 먼저 문자열에서 "://"를 검색하고, 발견되면 직접 반환한다는 사실을 발견했습니다. 따라서 ://로 매개변수를 전달하면 쿼리 문자열은 정상입니다. 우리 모두는 쿼리 문자열 매개변수가 urlencode되어야 한다는 것을 알고 있지만, 그렇지 않은 경우에도 여전히 URL에 허용되어야 합니다. 진지하게, 브라우저를 확인하십시오.
온라인에서 권장되는 접근 방식은 VirtualPathUtility.ToAbsolute를 사용하는 것입니다. 이는 URL을 쿼리 문자열로 전달하는 경우 매우 훌륭하고 편리합니다. 그렇지 않으면 예외가 발생합니다. 절대 URL인 경우에도 예외가 발생합니다!
그래서 나는 최종 해결책을 찾기로 결정했습니다.
먼저, 페이지 컨텍스트를 사용하지 않고 애플리케이션이 실행되는 동안 가상 경로를 제공할 좋은 변수를 찾고 있습니다.
저는 HttpRuntime.AppDomainAppVirtualPath를 사용했습니다. 타이머 콜백에서도 어디에서나 사용할 수 있습니다! 경로에 후행 슬래시가 없습니다. ASP.NET에서는 슬래시를 특이하게 제거했지만 수정할 수 있습니다. :-)
그런 다음 원본 ResolveUrl 코드를 사용하여 몇 가지 테스트를 수행하고 이를 AppVirtualPath로 바꾸는 방법을 알아냈습니다.
1. 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 || 상대Url[0] == '/' ||
상대Url[0] == '\') 상대Url을 반환합니다.
int idxOfScheme =
상대Url.IndexOf(@"://", StringComparison.Ordinal);
if (idxOfScheme != -1)
{
int idxOfQM = 상대Url.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;
boolfoundSlash; // 최신 문자가 슬래시였나요?
if (relativeUrl.Length > 1
&&relativeUrl[0] == '~'
&& (relativeUrl[1] == '/' || 상대Url[1] == '\'))
{
상대Url = 상대Url.Substring(2);
foundSlash = 참;
}
그렇지 않으면foundSlash = false;
foreach(relativeUrl의 문자 c)
{
만약 (!foundQM)
{
if (c == '?')foundQM = true;
또 다른
{
if (c == '/' || c == '\')
{
if (foundSlash) 계속;
또 다른
{
sbUrl.Append('/');
foundSlash = 참;
계속하다;
}
}
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
이 글의 저작권은 글쓴이에게 있으며, 재인쇄는 환영합니다. 단, 이 글은 글쓴이의 동의 없이 그대로 유지되어야 하며, 그렇지 않은 경우 원문에 대한 링크를 글 페이지의 눈에 띄는 위치에 제공해야 합니다. 법적 책임을 추구할 권리가 있습니다.