2011-06-08 36 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