HttpUtility.UrlEncode и Application_Start - PullRequest
5 голосов
/ 08 июня 2011

В соответствии с http://ayende.com/blog/4599/hunt-the-bug, я столкнулся с одним из тех сценариев, когда «Ответ недоступен в этом контексте».

Значительно упрощенное, в некоторых случаях в Windows Server 2008 / IIS7 / ASP.NET 4.0

возникает исключение
public class Global : HttpApplication
{
       public void Application_Start(object sender, EventArgs e)
       {
            HttpUtility.UrlEncode("Error inside!");
       }
}    

Решения, которые я видел, включают одно из следующих:

  1. Сделайте так, как это сделала Айенде, и "напишите мою собственную утилиту HttpUutil (ну, возьмите одну из Mono и измените ее), чтобы избежать этой ошибки."
  2. или определите, помогает ли использование HttpEncoder.Default. Я пытаюсь выяснить, как лучше это сделать.
  3. или используйте Uri.EscapeDataString согласно Server.UrlEncode против HttpUtility.UrlEncode

Может быть, это не мой лучший день поиска, но как реализовать HttpEncoder.Default?

Рекомендации

Ответы [ 2 ]

3 голосов
/ 24 июня 2011

Требуется ПОЛНОЕ доверие

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;
        }
    }
}
3 голосов
/ 23 июня 2011

Вы можете попробовать это для кодирования

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! ..

...