繁体   English   中英

如何再次请求中止的HttpWebRequest?

[英]How to request an aborted HttpWebRequest again?

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

当我中止() HttpWebRequest时,无法再次开始BeginGetResponse()。 因此,再次请求的唯一方法可能是重新创建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;
}

当您要重新发出相同的请求时,只需执行以下命令:

// 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对象,就像创建原始对象一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM