从HTTPWebRequest期间的NameResolutionFailure错误中恢复

时间:2019-04-26 22:40:23

标签: c# .net httpwebrequest

在Outlook COM加载项中,我们正在使用.NET HTTPWebRequest方法对服务器进行API调用。我们的一位客户正在以消息The remote name could not be resolved: 'mydomain.com'WebExceptionStatus.NameResolutionFailure作为状态运行到System.Net.WebException中。该特定客户公司的所有用户都在VPN后面使用Outlook /插件,因此我们要从IE附带代理配置,以便发出请求。

我们的API调用会工作一段时间,但随后会随机断开连接,然后不允许以后的请求通过其中任何一个。但是,一旦用户关闭并重新启动Outlook,它似乎可以再次正常运行,而无需更改任何网络配置或重新连接到wifi等。

诸如this之类的其他帖子建议在两次睡眠之间重试。我们添加了一种重试机制,该机制具有3次尝试,每次尝试之间都有一个睡眠,但是并不能解决间歇性问题。

我们的域已连接到AWS Classic负载均衡器,因此mydomain.com实际上将CNAME记录解析为一个指向ELB的AWS静态域。我不确定这是否会对请求或路由产生任何影响。

奇怪的是,我们还有一个Web浏览器组件,可从与API调用完全相同的域在侧边栏中加载网页。它可以完美运行并从同一域加载URL。用户还可以将URL加载到他们的浏览器中,而不会出现任何问题。似乎HTTPWebRequest正在运行域解析问题。我们检查了这不仅是因为无线信号较弱。由于他们能够使用具有相同代理配置的IE来访问站点,所以我认为不是那样。

我们对如何正常恢复并让请求重试感到困惑。我已经研究了this answer和这个other answer的建议,接下来我们将尝试这些建议。不幸的是,我们无法使请求使用直接IP地址,如其他答案所示。这也消除了编辑主机文件以使其直接指向该文件的能力。原因是我们无法在传统的ELB上分配静态IP。

我们正在考虑尝试将主机设置为直接使用来自AWS的CNAME记录,但这将导致SSL错误,因为它没有CNAME条目的有效证书。有没有一种方法可以通过类似于IP方法的标题通过屏蔽它来解决此问题?

随时询问更多信息,我会尽力提供。

欢迎尝试或解决问题的任何建议!

更新:我们的目标是.NET v4.5

这是代码

var result = string.Empty;
bool retrying = false;
int retries = 0;
HttpWebRequest webRequest = null;

try
{
    ServicePointManager.ServerCertificateValidationCallback =
        CertificateCheck;
    ServicePointManager.MaxServicePoints = 4;
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

retry:
    webRequest = (HttpWebRequest)WebRequest.Create(uriParam);
    webRequest.Timeout = 120000;
    webRequest.Method = "POST";
    webRequest.ContentType = "application/x-www-form-urlencoded";
    webRequest.Accept = acceptParam;
    webRequest.Headers.Add("Cookie", cookieParam);
    webRequest.UseDefaultCredentials = true;
    webRequest.Proxy = null;
    webRequest.KeepAlive = true; //default
    webRequest.ServicePoint.ConnectionLeaseTimeout = webRequest.Timeout;
    webRequest.ServicePoint.MaxIdleTime = webRequest.Timeout;
    webRequest.ContentLength = dataParam.Length;

    using (var reqStream = webRequest.GetRequestStream())
    {
        reqStream.Write(dataParam, 0, dataParam.Length);
        reqStream.Flush();
        reqStream.Close();
    }

    try
    {
        using (WebResponse webResponse = webRequest.GetResponse())
        {
            using (var responseStream = webResponse.GetResponseStream())
            {
                if (responseStream != null)
                {
                    using (var reader = new StreamReader(responseStream))
                    {
                        result = reader.ReadToEnd();
                    }
                }
            }
            webResponse.Close();
        }

    }
    catch (WebException)
    {
        if (retrying && retries == 3)
        {
            //don't retry any more
            return string.Empty;
        }

        retrying = true;
        retries++;
        webRequest.Abort();
        System.Threading.Thread.Sleep(2000);
        goto retry;
    }
}
catch (Exception ex)
{
    Log.Error(ex);
    result = string.Empty;
}
finally
{
    webRequest?.Abort();
}

return result;

0 个答案:

没有答案