HttpUtility.UrlEncode и Application_Start

Согласно 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. Сделайте то же, что и Айенде, и «напишите мою собственную HttpUtility (ну, возьмите ту из Mono и измените ее), чтобы избежать этой ошибки».
  2. или определить, помогает ли вместо этого использование HttpEncoder.Default. Я пытаюсь понять, как лучше это сделать.
  3. или используйте Uri.EscapeDataString согласно Server.UrlEncode против HttpUtility.UrlEncode

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

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


person Ted    schedule 08.06.2011    source источник


Ответы (2)


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

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

person Beygi    schedule 23.06.2011
comment
Молодец. Вот общедоступная статическая строка части отражения / декодирования UrlDecode (string urlPart) {return typeof (System.Net.WebClient) .Assembly .GetType (System.Net.HttpListenerRequest + Helpers) .InvokeMember (UrlDecodeStringFromStringInternal, BindingFlags.NonPags | BindingFlags.NonPags | .InvokeMethod, null, null, новый объект [] {urlPart, Encoding.UTF8}) в виде строки; } - person Dmitry Dzygin; 24.06.2011
comment
Спасибо за ответ. Отметили это как ответ, хотя я, скорее всего, собираюсь просто адаптировать моно-версию (см. github.com/mono/mono/blob/master/mcs/class/System.Web/) просто потому, что тогда я также могу уйти от зависимость от System.Web, которая существует только из-за HttpUtility.UrlEncode. - person Ted; 27.06.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;
        }
    }
}
person Dmitry Dzygin    schedule 24.06.2011
comment
Молодец! ..., но для тех, кто может подумать, что это сложно, нет, это не потому, что .net пропускает запрос к HttpContext.Current, если он равен нулю, а когда нет, именно тогда, когда ошибка проявляется сама. - person Beygi; 25.06.2011
comment
Спасибо за ответ. Хорошее решение, которое я буду использовать в будущем! Однако, хотя я, к сожалению, не упоминаю об этом в своем вопросе, полное доверие - это не вариант. - person Ted; 27.06.2011
comment
Хорошее решение. Хорошо сработало для меня. - person Jomy John; 07.06.2012