2011-06-08 10 views
5

Según http://ayende.com/blog/4599/hunt-the-bug, me encontré con uno de esos casos en los que "La respuesta no está disponible en este contexto".HttpUtility.UrlEncode y Application_Start

muy simplificada, la siguiente se produce una excepción en ciertos escenarios en Windows Server 2008/IIS7/ASP.NET 4,0

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

Las soluciones que he visto comprender uno de los siguientes:

  1. Haz lo que hizo Ayende y "escribe mi propia HttpUtility (bueno, toma la de Mono y modifícala) para evitar este error".
  2. o determinar si el uso de HttpEncoder.Default es el truco. Estoy tratando de encontrar la mejor manera de hacer esto.
  3. o utilizar Uri.EscapeDataString según Server.UrlEncode vs. HttpUtility.UrlEncode

Tal vez no es mi mejor día buscando en Google, pero la forma de aplicar HttpEncoder.Default?

Recomendaciones?

Respuesta

3

Puede probar esto para codificar

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; 
} 

Y si usted no se siente cómodo con su aplicación o no se está ejecutando en el nivel de plena confianza, intenta esto

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); 
    } 
} 

Sé que es todavía no es la mejor manera, pero ¿cuál podría ser la mejor manera si no usamos HttpUtility.UrlEncode! ..

+1

Buen trabajo. Aquí está la parte de reflexión/decodificador pública urldecode cadena estática (cadena urlPart) { retorno typeof (System.Net.WebClient) .assembly .GetType ("System.Net.HttpListenerRequest + ayudantes") .InvokeMember ("UrlDecodeStringFromStringInternal", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, nuevo objeto [] {urlPart, Encoding.UTF8}) como cadena; } –

+0

@DmitryDzygin gracias por el decodificador – Beygi

+1

Gracias por la respuesta. Lo he marcado como la respuesta, aunque es probable que simplemente adapte la versión mono (consulte https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility .cs) simplemente porque entonces también puedo alejarme de una dependencia en System.Web que solo está ahí debido a HttpUtility.UrlEncode. – Ted

3

Requiere FIDEICOMISO COMPLETO

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

¡Bien hecho! ..., pero para aquellos que puedan pensar que es complicado, no, no es porque .net está omitiendo la solicitud a HttpContext.Current si es nulo, y cuando no lo es, es exactamente cuando ese error se muestra por sí mismo. – Beygi

+0

Gracias por la respuesta. ¡Buena solución que tendré en cuenta para el futuro! Sin embargo, aunque desafortunadamente no lo menciono en mi pregunta, la confianza plena no es una opción. – Ted

+0

Buena solución. Funcionó bien para mí –

Cuestiones relacionadas