2011-06-08 38 views
5

根據http://ayende.com/blog/4599/hunt-the-bug,我遇到了其中一種情況,即「響應在此上下文中不可用」。HttpUtility.UrlEncode和Application_Start

大大簡化,以下Windows服務器上拋出在某些情況下例外2008/IIS7/ASP.NET 4.0

public class Global : HttpApplication 
{ 
     public void Application_Start(object sender, EventArgs e) 
     { 
      HttpUtility.UrlEncode("Error inside!"); 
     } 
}  

,我見過的解決方案包括以下之一:

  1. 就像Ayende所做的那樣,「寫我自己的HttpUtility(好吧,從Mono那裏拿一個修改它)來避免這個bug。」
  2. 或者確定是否使用HttpEncoder.Default來代替這個技巧。我試圖追蹤如何最好地做到這一點。
  3. 或使用Uri.EscapeDataString按Server.UrlEncode vs. HttpUtility.UrlEncode

也許這不是我最好的google搜索的一天,但如何實現HttpEncoder.Default?

建議?

回答

3

你可以試試這個編碼

public static string UrlEncode(string s) 
{ 
    return typeof(System.Net.WebClient).InvokeMember("UrlEncode", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new[] { "[#encoded] <data>" }) as string; 
} 

// by @DmitryDzygin 
public static string UrlDecode(string s) 
{ 
    return typeof(System.Net.WebClient).Assembly.GetType("System.Net.HttpListenerRequest+Helpers").InvokeMember("UrlDecodeStringFromStringInternal", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[] { s, Encoding.UTF8 }) as string; 
} 

如果你感覺不舒服或者你的應用程序不是在完全信任級別運行,試試這個

public class HttpUtils : System.Web.Util.HttpEncoder 
{ 
    private static HttpUtils _encoder; 
    internal static HttpUtils Encoder 
    { 
     get { return _encoder ?? (_encoder = new HttpUtils()); } 
    } 

    internal string InternalUrlEncode(string s) 
    { 
     var bytes = System.Text.Encoding.UTF8.GetBytes(s); 
     var encodedBytes = base.UrlEncode(bytes, 0, bytes.Length); 

     return System.Text.Encoding.UTF8.GetString(encodedBytes); 
    } 

    public static string UrlEncode(string s) 
    { 
     return Encoder.InternalUrlEncode(s); 
    } 
} 

我知道這是不仍然是最好的方式,但什麼可能最好的辦法是,如果我們不使用HttpUtility.UrlEncode!..

+1

幹得好。這裏的反射器/解碼器部分公共靜態字符串UrlDecode(字符串urlPart) { 回報的typeof(System.Net.WebClient) .Assembly .GetType( 「System.Net.HttpListenerRequest +助手」) .InvokeMember( 「UrlDecodeStringFromStringInternal」 BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod,null,null, new object [] {urlPart,Encoding.UTF8})as string; } – 2011-06-24 09:12:01

+0

@DmitryDzygin感謝解碼器 – Beygi 2011-06-24 09:42:17

+1

感謝您的迴應。已經標記爲答案,即使我可能只是適應單聲道版本(請參閱https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility .cs),因爲那樣我也可以從System.Web的依賴關係中解脫出來,因​​爲它只是因爲HttpUtility.UrlEncode而存在。 – Ted 2011-06-27 17:57:40

3

需要完全信任

public static class DefaultHttpEncoder 
{ 
    public static string UrlEncode(string urlPart) 
    { 
     using (new NoHttpContext()) 
     { 
      return HttpUtility.UrlEncode(urlPart); 
     } 
    } 

    public static string UrlDecode(string urlPart) 
    { 
     using (new NoHttpContext()) 
     { 
      return HttpUtility.UrlDecode(urlPart); 
     } 
    } 

    private class NoHttpContext : IDisposable 
    { 
     private readonly HttpContext _context; 

     public NoHttpContext() 
     { 
      _context = HttpContext.Current; 
      HttpContext.Current = null; 
     } 

     public void Dispose() 
     { 
      HttpContext.Current = _context; 
     } 
    } 
} 
+0

幹得好!......但對於那些可能認爲它很棘手的人來說,不,這不是因爲.net會跳過對HttpContext.Current的請求,如果它爲空,並且什麼時候不是,那麼錯誤就會顯示它自己。 – Beygi 2011-06-25 12:24:52

+0

感謝您的回覆。我將爲未來記住的好解決方案!然而,雖然我不幸在我的問題中沒有提及,但完全信任不是一種選擇。 – Ted 2011-06-27 17:55:12

+0

好的解決方案。爲我工作得很好。 – 2012-06-07 09:30:46