I have an asynchronous library that connects to a third party system API. I am trying to use this library within a Dynamics C# plugin to create a new record in the third party system. The code I have written works fine whenever the plugin only runs on one entity at a time. However, if I kick off the plugin on two different entities at the same time I receive the error:
Failed to update Star. Error - Object reference not set to an instance of an object. : System.NullReferenceException : : at COHEN.APIConnector.Connectors.StarConnector.d__2`1.MoveNext()
I'm not quite sure what is causing this error or how to resolve it. It seems to have something to do with the asynchronous nature of the library I have written to connect to the API. What would cause this error and what are some options to resolve it?
Plugin Code
APIResponse<COHEN.APIConnector.Model.Entity.ContractJob> response = new APIResponse<COHEN.APIConnector.Model.Entity.ContractJob>();
Task.WaitAll(Task.Run(async () => response = await starConnector.Create(starJob)));
Library Code
public async Task<APIResponse<T>> Create<T>(T entity) where T : EntityBase
{
APIResponse<T> response = new APIResponse<T>();
try
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(Helpers.GetSystemUrl(Application.Star));
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
response.RequestURL = "Calling ToJSON";
string json = await entity.ToJSON(Application.Star);
response.RequestURL = "JSON: " + json;
response.RequestURL = "RunTask?taskid=" + (int)TaskID.CREATE + "&entity=" +
await MapSingleton.Instance.GetFieldName(Application.Star, entity.Type, FieldType.EntityName) +
"&json=" + json;
using (HttpResponseMessage responseMessage = await client.GetAsync(
"RunTask?taskid=" + (int)TaskID.CREATE + "&entity=" +
await MapSingleton.Instance.GetFieldName(Application.Star, entity.Type, FieldType.EntityName) +
"&json=" + json
))
{
// Check TaskCentre response
if (responseMessage.StatusCode == HttpStatusCode.OK)
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(await responseMessage.Content.ReadAsStringAsync());
// Check API Response
string responseStatusCode = xmlDocument.GetElementsByTagName("StatusCode").Item(0).InnerText;
if (responseStatusCode != "")
{
StatusCode statusCode = (StatusCode)Convert.ToInt32(responseStatusCode);
string statusMessage = xmlDocument.GetElementsByTagName("StatusMessage").Item(0).InnerText;
if (statusCode == StatusCode.Created)
{
XmlDocument xmlData = new XmlDocument();
xmlData.LoadXml("<data>" + xmlDocument.InnerText.Substring(0, xmlDocument.InnerText.Length - (xmlDocument.InnerText.Length - xmlDocument.InnerText.LastIndexOf("row") - 4)) + "</data>");
JObject data = JObject.Parse(JsonConvert.SerializeXmlNode(xmlData));
await response.SetValues(Application.Star, entity.Type, data["data"]["row"], entity.ID);
}
response.StatusCode = statusCode;
response.StatusReason = statusMessage;
}
else
{
response.StatusCode = StatusCode.Error;
response.StatusReason = "No Status Code Returned - " + response.StatusReason;
}
}
else
{
response.StatusCode = (StatusCode)responseMessage.StatusCode;
response.StatusReason = responseMessage.ReasonPhrase;
}
}
}
}
catch (Exception e)
{
response.StatusCode = StatusCode.Error;
response.StatusReason = e.Message + " : " + e.GetType().ToString() + " : " + e.InnerException + " : " + e.StackTrace;
}
return response;
}