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!");
}
}
Решения, которые я видел, включают одно из следующих:
- Сделайте как Ayende и "напишите мою собственную HttpUtility (ну, возьмите одну из Mono и измените ее), чтобы избежать этой ошибки".
- или определите, использует ли вместо этого HttpEncoder.Default. Я пытаюсь выяснить, как лучше это сделать.
- или используйте Uri.EscapeDataString в соответствии с Server.UrlEncode против HttpUtility.UrlEncode
Может быть, это не мой лучший день поиска в Google, но как реализовать HttpEncoder.Default?
Рекомендации?
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!..
Требуется ПОЛНОЕ доверие
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;
}
}
}