【发布时间】:2011-12-06 15:32:57
【问题描述】:
如果您将 Thread.CurrentThread.CurrentCulture 更改为不同于已安装的内容(操作系统文化),则对 HttpWebRequest.GetResponse() 的调用将始终超时。
为了澄清,这里是我的实用程序类的内容,它正在做脏活:
private static void ReplicateCookies(HttpWebRequest request)
{
if (HttpContext.Current == null)
return;
if (request.CookieContainer == null)
request.CookieContainer = new CookieContainer();
foreach (var cookie in from object key in HttpContext.Current.Request.Cookies.Keys select HttpContext.Current.Request.Cookies[key.ToString()])
request.CookieContainer.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, string.IsNullOrEmpty(cookie.Domain)
? HttpContext.Current.Request.Url.Host
: cookie.Domain));
}
private HttpWebRequest CreateRequest(string url, string method = null)
{
var httpRequest = WebRequest.Create(url) as HttpWebRequest;
ReplicateCookies(httpRequest);
httpRequest.KeepAlive = false;
httpRequest.Method = method ?? "GET";
httpRequest.Timeout = 20000;
httpRequest.Proxy = null;
httpRequest.ServicePoint.ConnectionLeaseTimeout = 20000;
httpRequest.ServicePoint.MaxIdleTime = 10000;
return httpRequest;
}
public string ReadWebPage(string url)
{
var oldCulture = Thread.CurrentThread.CurrentCulture.Name;
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");
string result;
var httpRequest = CreateRequest(url);
httpRequest.Headers.Add("Accept-Language", oldCulture);
try
{
using (var httpResponse = httpRequest.GetResponse())
{
using (var stream = httpResponse.GetResponseStream())
{
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();
reader.Close();
}
stream.Flush();
stream.Close();
}
httpResponse.Close();
}
}
finally
{
httpRequest.Abort();
}
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo(oldCulture);
return result;
}
如果你想知道:
- 在 ReplicateCookies 中,如果您使用 null 作为域调用 CookieCONtainer.Add,它将在运行时失败
- 代码已经包含解决 CurrentCulture 问题的修复程序。继续,取出所有改变文化的代码,将你的线程文化设置为某种东西(例如“fr-FR”)并给代码一个旋转。
我已经确定:
- 没有代理干扰请求
- 没有防火墙设置阻止这样的请求
也许值得一提的是,它在 MVC3 Web 应用程序内部用于生成模板化消息 - 其中模板就是网页本身。应用程序将其文化设置为这样 (Global.asax.cs):
protected void Application_AcquireRequestState()
{
if (HttpContext.Current == null)
return;
if (HttpContext.Current.Session == null)
return;
if (HttpContext.Current.Session["Culture"] != null)
CultureHelper.SetCulture(HttpContext.Current.Session["Culture"].ToString());
}
还有助手类:
public static class CultureHelper
{
public static void SetCulture(string culture)
{
if (string.IsNullOrEmpty(culture))
return;
var cultureInfo = new CultureInfo(culture);
if (culture.ToLower().Equals("fr-fr") || culture.ToLower().Equals("fr"))
cultureInfo.NumberFormat.NumberGroupSeparator = cultureInfo.NumberFormat.CurrencyGroupSeparator = ".";
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
}
出于某种原因,法语默认使用空格作为千位分隔符 - 因此是 if 语句。
ReplicateCookies 方法会将会话 cookie 和身份验证 cookie 复制到内部请求,以便会话/身份验证保留在生成的内部请求中。
该网站显然有办法改变当前的文化(改变会话值)。在 ReadWebPage 方法中的修复之前,一切都会正常工作,直到文化改变。之后,每个 HttpWebRequest.GetResponse 都会超时,直到文化变回 - 在我的情况下 - en-GB。
任何想法为什么会发生这种情况?我可能在某个地方做错了什么。正如我所说,它在当前状态下工作。只是不是很漂亮。
【问题讨论】:
标签: c# http httpwebrequest timeout cultureinfo