2011-12-06 62 views
1

Thread.CurrentThread.CurrentCultureをインストール済み(OSカルチャ)と異なるものに変更した場合、HttpWebRequest.GetResponse()の呼び出しは常にタイムアウトします。ただ、明確化のため、ここに汚い仕事をしている私のユーティリティクラスの内容はThread.CurrentThread.CurrentCultureが変更された場合、HttpWebRequestがタイムアウトします

です:

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で

  • を、あなたはCookieCOntainer.Addを呼び出す場合実行時にドメインとしてnullが返されます。
  • このコードには、CurrentCultureの問題を回避する修正が含まれています。続けて、文化を変えているコードをすべて取り出し、糸文化を何か(例えば "fr-FR")にして、コードをスピンします。何のプロキシがファイアウォールの設定は、おそらくそれは、これは内部使用されたことを言及する価値があります。この

のような要求を防ぐない要求

  • に干渉されていない

    • :私がいることを確認してください作った

    内部的にテンプレート化されたメッセージを生成するMVC3 Webアプリケーション - テンプレートは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メソッドはセッションクッキーと認証クッキーを内部リクエストにコピーし、結果として得られる内部リクエストでセッション/認証が保持されるようにします。

    サイトには明らかに現在のカルチャを変更する手段があります(セッション値を変更する)。 ReadWebPageメソッドの修正に先立って、カルチャが変更されるまではすべて正常に機能します。その後、すべてのHttpWebRequest.GetResponseは、文化が私のケースではen-GBに変更されるまでタイムアウトします。

    なぜこれが起こっているすべてのアイデア?私はどこかで大げさに何かをやっている可能性があります。私が言ったように、それは現在の状態です。それはあまりあてにはならない。

  • 答えて

    2

    すべての人がこの記事をすばやく削除しようとする前に、誰もそれが失敗したと見なすので、解決策があります。いつものように、それはあなたが決して考えることのない1つのことでした。私は "ここにあなたの頭を叩く!"黒い点がある場合は、訂正されたコードを次に示します。

    private static void ReplicateCookies(HttpWebRequest request) 
    { 
        if (HttpContext.Current == null) 
         return; 
        if (request.CookieContainer == null) 
         request.CookieContainer = new CookieContainer(); 
        foreach (var cookieKey in HttpContext.Current.Request.Cookies.Keys) 
        { 
         if (!cookieKey.ToString().Equals("ASP.NET_SessionId")) 
         { 
          var cookie = HttpContext.Current.Request.Cookies[cookieKey.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; 
        httpRequest.Headers.Add("Accept-Language", Thread.CurrentThread.CurrentCulture.Name); 
        return httpRequest; 
    } 
    
    public string ReadWebPage(string url) 
    { 
        string result; 
        var httpRequest = CreateRequest(url); 
        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(); 
        } 
        return result; 
    } 
    

    説明:問題はReplicateCookiesメソッドにありました。他のすべての中でそれはASPセッションクッキーを書き換えていました。そして、同じプロセスへの呼び出しを行っていたので、最初のリクエストからのセッションがロックされていたために、後でハングアップし(そして最終的にタイムアウトしました)、着信リクエストが同じセッションを使用しようとしていました。

    壁にマグネットの大きな黒い点をぶら下げています...

    関連する問題