asp.net中的ResolveUrl 完美解決方案

來源:互聯網
上載者:User

     根據我個人使用ASP.NET的經驗,和通過在網上搜尋。我發現,Page的ResolveUrl方法給我們帶來了一些比較嚴重的問題。

     最常見的問題是在頁面或控制項以外的範圍不能使用它。

     其他的問題都是bug。如它不能正確處理一些你給的URL。例如,嘗試 Page.ResolveUrl("~/test.aspx?param=http://www.test.com")。結果與你輸入字串相同,沒做任何變動。使用Reflector查看asp.net代碼,我發現將相對URL轉換為絕對URL機制都是先搜尋string中的 "://",如果找到,就直接返回了。因此,如果你傳遞一個帶://的參數,查詢字串就是OK的。我們都知道的查詢字串參數應進行urlencode,但如果沒有,它應該仍然是可以接受URL。嚴重的是,要檢查您的瀏覽器。

   網上,建議的方法是使用VirtualPathUtility.ToAbsolute,如果你在傳遞URL作為查詢字串,這是相當不錯和方便的,...否則,就會引發異常。如果是一個絕對URL,它也會拋出異常!
   所以,我決定尋求一個最終解決方案。

   首先,我要找搜尋一個很好的變數,它能給我們在應用程式運行時的虛擬路徑,不使用頁面上下文。

   我使用了HttpRuntime.AppDomainAppVirtualPath。它能在任何地方使用-甚至在timer callback中!它沒有尾隨斜線路徑,ASP.NET作了特素處理,消除斜杠,不過,我們能修複它:-)

   然後,我使用原ResolveUrl代碼做了一些測試,找到怎麼用AppVirtualPath取代:

1、當URL以斜線開始(/或\),也不會改動它!

2、當URL以〜/開始,它會被AppVirtualPath取代。

3、當URL是一個絕對URL,也不會改變它

4、在任何其他情況下(甚至以〜開始,而不是斜杠),將追加URL到AppVirtualPath。

5、每當它修改URL,還修複斜杠。刪除雙斜線,用/替換\。

代碼:

代碼

public static string ResolveUrl(string relativeUrl)
{
    if (relativeUrl == null) throw new ArgumentNullException("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;
    }

    StringBuilder sbUrl = new StringBuilder();
    sbUrl.Append(HttpRuntime.AppDomainAppVirtualPath);
    if (sbUrl.Length == 0 || sbUrl[sbUrl.Length - 1] != '/') sbUrl.Append('/');

    // found question mark already? query string, do not touch!
    bool foundQM = false;
    bool foundSlash; // the latest char was a slash?
    if (relativeUrl.Length > 1
        && relativeUrl[0] == '~'
        && (relativeUrl[1] == '/' || relativeUrl[1] == '\\'))
    {
        relativeUrl = relativeUrl.Substring(2);
        foundSlash = true;
    }
    else foundSlash = false;
    foreach (char c in relativeUrl)
    {
        if (!foundQM)
        {
            if (c == '?') foundQM = true;
            else
            {
                if (c == '/' || c == '\\')
                {
                    if (foundSlash) continue;
                    else
                    {
                        sbUrl.Append('/');
                        foundSlash = true;
                        continue;
                    }
                }
                else if (foundSlash) foundSlash = false;
            }
        }
        sbUrl.Append(c);
    }

    return sbUrl.ToString();
}

     在完成代碼後和比較原來ResolveUrl測試一遍又一遍,我開始測試效能...在大多數情況下,My Code執行速度比原來快ResolveUrl 2.7倍!我也在迴圈內部進行測試,用不同的URL執行代碼100000次。

參考原文:http://www.codeproject.com/KB/aspnet/resolveurl.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.