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