中止されたHttpWebRequestを再度要求するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/411974

  •  03-07-2019
  •  | 
  •  

質問

私の目的は、非同期のHttpWebRequestが失敗したときに再試行することです。

Abort()の場合HttpWebRequest、BeginGetResponse()を再度することはできません。したがって、おそらく再度リクエストする唯一の方法は、おそらくHttpWebRequestオブジェクトを再作成することです。古いオブジェクトからすべてのプロパティをコピーする必要があるため、多くの作業が必要なようです。ショートカットはありますか?

注:シリアル化で問題は解決すると思いますが、前の質問

更新不要であるためサンプルソースコードを削除しました

この問題の現在の表示ショートカットはありません。リクエストをやり直す唯一の方法は、元のオブジェクトを作成したのと同じ方法で別のHttpWebRequestオブジェクトを作成することです。

役に立ちましたか?

解決

それは可能です!

新しい HttpWebRequest を作成し、すべてのプロパティをリフレクションを介して古いオブジェクトからコピーする必要があります。

これを行う拡張メソッドは次のとおりです。

/// <summary>
/// Clones a HttpWebRequest for retrying a failed HTTP request.
/// </summary>
/// <param name="original"></param>
/// <returns></returns>
public static HttpWebRequest Clone(this HttpWebRequest original)
{
    // Create a new web request object
    HttpWebRequest clone = (HttpWebRequest)WebRequest.Create(original.RequestUri.AbsoluteUri);

    // Get original fields
    PropertyInfo[] properties = original.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

    // There are some properties that we can't set manually for the new object, for various reasons
    List<string> excludedProperties = new List<String>(){ "ContentLength", "Headers" };

    // Traverse properties in HttpWebRequest class
    foreach (PropertyInfo property in properties)
    {
        // Make sure it's not an excluded property
        if (!excludedProperties.Contains(property.Name))
        {
            // Get original field value
            object value = property.GetValue(original);

            // Copy the value to the new cloned object
            if (property.CanWrite)
            {
                property.SetValue(clone, value);
            }
        }
    }

    return clone;
}

同じリクエストを再発行する場合は、次を実行します。

// Create a request
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/");

// Change some properties...

// Execute it
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

// Clone the request to reissue it using our extension method
request = request.Clone();

// Execute it again
response = (HttpWebResponse)request.GetResponse();

他のヒント

それは不可能です。

HTTPWebRequestインスタンスは、文字通り1つのリクエストインスタンスを表しますが(内部的に再試行するエッジケースがある場合もあります)、したがって論理的に繰り返すことができるものではありません。正確に1つの応答を返すことができます(要求/応答は論理ペアです)。その応答を複数回検査できますが、まったく同じオブジェクトを取得できます。

基本的に、HTTPWebRequestインスタンスは一種のファクトリーであると考えていますが、実際には具体的です。別のインスタンスを作成する必要があります。

リクエストをどこでシリアライズしようとしていますか?リクエストを行う前にリクエストをシリアル化してから、失敗した場合にリクエストを(シリアル化されたインスタンスから)再送することをお勧めします。

また、プロキシを削除し、インスタンスをシリアル化してから、プロキシを元に戻すこともできます。これは、リクエストのシリアル化で問題が発生しているようだからです。

ショートカットはありません。リクエストをやり直す唯一の方法は、元のオブジェクトと同じ方法で別のHttpWebRequestオブジェクトを作成することです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top