Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何再次请求中止的HttpWebRequest?_C#_.net_Httpwebrequest - Fatal编程技术网

C# 如何再次请求中止的HttpWebRequest?

C# 如何再次请求中止的HttpWebRequest?,c#,.net,httpwebrequest,C#,.net,Httpwebrequest,我的目标是在异步HttpWebRequest失败时重试它 当我请求HttpWebRequest时,我无法再次开始响应()。因此,再次请求的唯一方法可能是重新创建HttpWebRequest对象。这似乎需要很多工作,因为我必须从旧对象复制所有属性。有捷径吗 注意:我认为序列化可以解决我的问题,但是这个类不会序列化,正如在一篇文章中讨论的那样 更新删除了示例源代码,因为它是不必要的 关于这个问题的当前观点没有捷径,重做请求的唯一方法是以创建原始HttpWebRequest对象的相同方式创建另一个Ht

我的目标是在异步HttpWebRequest失败时重试它

当我请求HttpWebRequest时,我无法再次开始响应()。因此,再次请求的唯一方法可能是重新创建HttpWebRequest对象。这似乎需要很多工作,因为我必须从旧对象复制所有属性。有捷径吗

注意:我认为序列化可以解决我的问题,但是这个类不会序列化,正如在一篇文章中讨论的那样

更新删除了示例源代码,因为它是不必要的


关于这个问题的当前观点没有捷径,重做请求的唯一方法是以创建原始HttpWebRequest对象的相同方式创建另一个HttpWebRequest对象。

在哪里尝试序列化请求?在尝试发出请求之前序列化请求,然后在失败时(从序列化实例)重新发送请求,这可能是一个好主意


此外,您可能希望删除代理,序列化实例,然后将代理设置回原位,因为序列化请求似乎就是问题所在。

没有快捷方式,重做请求的唯一方法是以与创建原始HttpWebRequest对象相同的方式创建另一个HttpWebRequest对象。

这是不可能的

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;
}

完整代码不包含序列化,因为它不起作用,但是如果我在代码中包含序列化,我肯定会按照您所说的做。我为序列化测试编写的代码没有关于代理的任何行,我不知道如何删除它。是否删除了序列化示例代码,并将其替换为指向另一个的链接,因此关于序列化HttpWebRequest()的问题有一种方法,请查看我的答案。谢谢,好主意!但是,我不确定您不想复制哪些标题。例如,如果您有授权信息,则需要复制头(至少其中一些),以便下次尝试成功。扩展方法不会复制头,因为C#在尝试将整个头写入该属性时会引发异常。您需要调整代码,将每个单独的头作为键、值对读取,并将其写入新的克隆对象中,每次读取一个头。
// 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();