繁体   English   中英

VSTO Outlook 插件 - HttpClient.PostAsync 在没有提琴手的情况下失败

[英]VSTO Outlook Plugin - HttpClient.PostAsync fails without fiddler

不幸的是,我在插件中开发此功能的整个过程中一直运行 Fiddler,自从部署到客户端后,我发现它不适用于任何人 - 除非他们也运行 fiddler! 如果我停止运行 Fiddler,它也不适用于我的开发机器。

主要错误是Error while copying content to a stream. . 所以,我调查的数据的可能性,我POST荷兰国际集团由GC被释放之前完成击球的服务器(这对我来说,解释了为什么跑提琴手解决了这个问题-因为我相信请求得到第一,然后送到提琴手Fiddler 将其发送到服务器)。 但是我找不到任何支持这可能是问题的东西。 我曾尝试确保它保留数据,但我不觉得我走在正确的道路上。

代码大致是这样的:

HttpClientHandler httpHandler = new HttpClientHandler { UseDefaultCredentials = true };
var client = new HttpClient(httpHandler, false);
client.BaseAddress = new Uri(BaseUrl + "api/job/PostTest");

var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture));

content.Add(new StringContent(mailItem.HTMLBody, Encoding.UTF8), "BodyHtml");
// content.Add()'s... Omitted for brevity

var response = client.PostAsync(BaseUrl + "api/job/PostTest", content);

response.ContinueWith(prevTask => {

    if (prevTask.Result.IsSuccessStatusCode)
    {
        System.Diagnostics.Debug.WriteLine("Was success");
    }
    else
    {
        System.Diagnostics.Debug.WriteLine("Was Error");
    }

}, System.Threading.Tasks.TaskContinuationOptions.OnlyOnRanToCompletion);



response.ContinueWith(prevTask =>{
    MessageBox.Show(prevTask.Exception.ToString());
}, System.Threading.Tasks.TaskContinuationOptions.OnlyOnFaulted);

完整的异常详细信息是:

   System.AggregateException: One or more errors occurred. ---> System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.Net.WebException: The request was aborted: The request was canceled.
   at System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
   at System.Net.Http.StreamToStreamCopy.StartRead()
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.Net.WebException: The request was aborted: The request was canceled.
   at System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
   at System.Net.Http.StreamToStreamCopy.StartRead()
   --- End of inner exception stack trace ---<---

如果有人可以向我指出一些对我有帮助的资源或指出我哪里出错了,那将大有帮助!

在开发IronBox Outlook插件时,我们遇到了这个问题。 我们发现,在 VSTO 上下文中,ServicePointManager 支持的安全协议只有 TLS 和 Ssl3(这不适用于我们仅支持 TLS 1.2 或更高版本的 API)。

您可以像这样从 VSTO 代码中轻松检查这一点(这是我们挂钩 Application.ItemSend 事件时的示例):

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    // Handle event when item is sent
    this.Application.ItemSend += Application_ItemSend;        
}

private void Application_ItemSend(object Item, ref bool Cancel)
{
    foreach (var c in (SecurityProtocolType[])Enum.GetValues(typeof(SecurityProtocolType)))
    {
        if (ServicePointManager.SecurityProtocol.HasFlag(c))
        {
            Debug.WriteLine(c.ToString());
        }
    }
    Cancel = false;
}

我们通过设置 ServicePointManager.SecurityProtocol 属性来支持 Tls12 来解决它,如下所示:

ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

希望有一天这能帮助某人,

凯文

经过大量搜索和大量混乱之后,我无法使用HttpClient解决这个问题,所以我所做的是使用WebClient 如果将来有人遇到这个问题,我将发布我最终使用的内容:

System.Net.WebClient wc = new System.Net.WebClient();
wc.Headers.Add("Content-Type", String.Format("multipart/form-data; boundary=\"{0}\"", multipartFormBoundary));
wc.UseDefaultCredentials = true;

try
{
    var wcResponse = wc.UploadData(BaseUrl + "api/job/PostJobEmailNote", byteArray);
}
catch(Exception e)
{
    // response status code was not in 200's 
}

我认为问题可能在于使用返回 void 的匿名函数。 他们有点问题。 将我的 lambda 更改为返回 bool 的 lambda 为我解决了这个问题。

暂无
暂无

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

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