在 Dynamics CRM 中的自定义工作流 activity 中使用 httpClient 发送 POST 请求会引发异常 "ThreadAbortException"
Sending a POST request using httpClient in a custom workflow activity in Dynamics CRM throws an exception "ThreadAbortException"
我的任务是检索在名为“Denunciation”的实体中创建的数据,然后进行一些结构化并将此数据(以 JSON 字符串格式)发送到 API,因此我需要发出 POST 请求,一切正常,但是当我想发送 post 请求时,它抛出这个 Excpetion
异常详情:
System.Threading.ThreadAbortException
HResult=0x80131530
Message=The thread has been abandoned.
Source=System
StackTrace:
at System.Net.CookieModule.OnSendingHeaders(HttpWebRequest httpWebRequest)
at System.Net.HttpWebRequest.UpdateHeaders()
at System.Net.HttpWebRequest.SubmitRequest(ServicePoint servicePoint)
at System.Net.HttpWebRequest.BeginGetRequestStream(AsyncCallback callback, Object state)
at System.Net.Http.HttpClientHandler.StartGettingRequestStream(RequestState state)
at System.Net.Http.HttpClientHandler.PrepareAndStartContentUpload(RequestState state)
--- End of stack trace from previous location ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at HclsDeclareProspect.DeclareProspect.<Execute>d__28.MoveNext() in C:\Users\aimad.quouninich\Desktop\Projects\VDN\HclsDeclareProspect\DeclareProspect.cs:line 177
This exception was originally thrown at this call stack:
[External Code]
HclsDeclareProspect.DeclareProspect.Execute(System.Activities.CodeActivityContext) in DeclareProspect.cs
我在执行方法中的代码:
// Send POST request APIM
CanalItem endpoint = CanalProvider.Retrieve(service, endpointReference);
_trace += string.Format("Endpoint : {0} \r\n", endpoint.Name);
_trace += string.Format("Endpoint Url : {0} \r\n", endpoint.Url);
_trace += string.Format("Endpoint Login : {0} \r\n", endpoint.Login);
_trace += string.Format("Endpoint Login : {0} \r\n", endpoint.Password);
string url = $"{endpoint.Url}/denunciation";
var content = new StringContent(requestJSON.ToString(), Encoding.UTF8, "application/json");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Apim-Subscription-Key", endpoint.Password);
try
{
var result = await client.PostAsync(url, content);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
如果我删除了 try-catch 块,自定义工作流和 pluginRegistrationTool 将退出而不显示任何错误消息,并且后续行代码将不会执行。
我已经尝试了很多事情,比如使用 httpWebRequest 而不是 httpClient,但是当我尝试写入流时,它存在这个错误
System.Security.SecurityException
HResult=0x8013150A
Message=Type Authorization Request Failed 'System.Net.WebPermission, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Source=mscorlib
StackTrace:
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.Net.HttpWebRequest.get_Proxy()
at System.Net.WebRequest.GetRequestStreamAsync()
at HclsDeclareProspect.DeclareProspect.<Execute>d__29.MoveNext() in C:\Users\aimad.quouninich\Desktop\Projects\VDN\HclsDeclareProspect\DeclareProspect.cs:line 186
This exception was originally thrown at this call stack:
[External Code]
HclsDeclareProspect.DeclareProspect.Execute(System.Activities.CodeActivityContext) in DeclareProspect.cs
将此代码用于 HttpWebrequest 代替 httpClient:
string url = $"{endpoint.Url}/denunciation";
var content = new StringContent(requestJSON.ToString(), Encoding.UTF8, "application/json");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var request = (HttpWebRequest)WebRequest.Create(new Uri(url));
request.ContentType = "application/json";
request.Method = "POST";
request.Timeout = 4000; //ms
var itemToSend = JsonConvert.SerializeObject(requestJSON);
using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
streamWriter.Write(itemToSend);
streamWriter.Flush();
streamWriter.Dispose();
}
// Send the request to the server and wait for the response:
using (var response = await request.GetResponseAsync())
{
// Get a stream representation of the HTTP web response:
using (var stream = response.GetResponseStream())
{
var reader = new StreamReader(stream);
var message = reader.ReadToEnd();
}
}
我不知道该怎么做,请提供任何帮助。
已解决,
问题出在 Newtonsoft.json 包中。看起来 CRM 不接受 extern packages/assemblies 并且工具 Ilmerge(合并多个程序集)已被弃用并且不再受 CRM 支持。
当 运行 调试器和进程异步时,我没有注意到问题并且工作正常,所以我删除了 Newtonsoft.json 并使用了 built-in 解决方案,即 DataContractSerializer然后使用跟踪日志我能够看到 post 工作正常,但在调试时它不起作用程序只是退出,解决方案是在 post 请求代码行之后放置断点以便能够看到结果。
希望对遇到同样问题的其他人有所帮助。
我的任务是检索在名为“Denunciation”的实体中创建的数据,然后进行一些结构化并将此数据(以 JSON 字符串格式)发送到 API,因此我需要发出 POST 请求,一切正常,但是当我想发送 post 请求时,它抛出这个 Excpetion
异常详情:
System.Threading.ThreadAbortException
HResult=0x80131530
Message=The thread has been abandoned.
Source=System
StackTrace:
at System.Net.CookieModule.OnSendingHeaders(HttpWebRequest httpWebRequest)
at System.Net.HttpWebRequest.UpdateHeaders()
at System.Net.HttpWebRequest.SubmitRequest(ServicePoint servicePoint)
at System.Net.HttpWebRequest.BeginGetRequestStream(AsyncCallback callback, Object state)
at System.Net.Http.HttpClientHandler.StartGettingRequestStream(RequestState state)
at System.Net.Http.HttpClientHandler.PrepareAndStartContentUpload(RequestState state)
--- End of stack trace from previous location ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at HclsDeclareProspect.DeclareProspect.<Execute>d__28.MoveNext() in C:\Users\aimad.quouninich\Desktop\Projects\VDN\HclsDeclareProspect\DeclareProspect.cs:line 177
This exception was originally thrown at this call stack:
[External Code]
HclsDeclareProspect.DeclareProspect.Execute(System.Activities.CodeActivityContext) in DeclareProspect.cs
我在执行方法中的代码:
// Send POST request APIM
CanalItem endpoint = CanalProvider.Retrieve(service, endpointReference);
_trace += string.Format("Endpoint : {0} \r\n", endpoint.Name);
_trace += string.Format("Endpoint Url : {0} \r\n", endpoint.Url);
_trace += string.Format("Endpoint Login : {0} \r\n", endpoint.Login);
_trace += string.Format("Endpoint Login : {0} \r\n", endpoint.Password);
string url = $"{endpoint.Url}/denunciation";
var content = new StringContent(requestJSON.ToString(), Encoding.UTF8, "application/json");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Apim-Subscription-Key", endpoint.Password);
try
{
var result = await client.PostAsync(url, content);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
如果我删除了 try-catch 块,自定义工作流和 pluginRegistrationTool 将退出而不显示任何错误消息,并且后续行代码将不会执行。
我已经尝试了很多事情,比如使用 httpWebRequest 而不是 httpClient,但是当我尝试写入流时,它存在这个错误
System.Security.SecurityException
HResult=0x8013150A
Message=Type Authorization Request Failed 'System.Net.WebPermission, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Source=mscorlib
StackTrace:
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.Net.HttpWebRequest.get_Proxy()
at System.Net.WebRequest.GetRequestStreamAsync()
at HclsDeclareProspect.DeclareProspect.<Execute>d__29.MoveNext() in C:\Users\aimad.quouninich\Desktop\Projects\VDN\HclsDeclareProspect\DeclareProspect.cs:line 186
This exception was originally thrown at this call stack:
[External Code]
HclsDeclareProspect.DeclareProspect.Execute(System.Activities.CodeActivityContext) in DeclareProspect.cs
将此代码用于 HttpWebrequest 代替 httpClient:
string url = $"{endpoint.Url}/denunciation";
var content = new StringContent(requestJSON.ToString(), Encoding.UTF8, "application/json");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var request = (HttpWebRequest)WebRequest.Create(new Uri(url));
request.ContentType = "application/json";
request.Method = "POST";
request.Timeout = 4000; //ms
var itemToSend = JsonConvert.SerializeObject(requestJSON);
using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
streamWriter.Write(itemToSend);
streamWriter.Flush();
streamWriter.Dispose();
}
// Send the request to the server and wait for the response:
using (var response = await request.GetResponseAsync())
{
// Get a stream representation of the HTTP web response:
using (var stream = response.GetResponseStream())
{
var reader = new StreamReader(stream);
var message = reader.ReadToEnd();
}
}
我不知道该怎么做,请提供任何帮助。
已解决,
问题出在 Newtonsoft.json 包中。看起来 CRM 不接受 extern packages/assemblies 并且工具 Ilmerge(合并多个程序集)已被弃用并且不再受 CRM 支持。
当 运行 调试器和进程异步时,我没有注意到问题并且工作正常,所以我删除了 Newtonsoft.json 并使用了 built-in 解决方案,即 DataContractSerializer然后使用跟踪日志我能够看到 post 工作正常,但在调试时它不起作用程序只是退出,解决方案是在 post 请求代码行之后放置断点以便能够看到结果。
希望对遇到同样问题的其他人有所帮助。