Search code examples
c#dynamics-crmdynamics-365

Resolve Incident in D365 Online via OData


I have created a controller for one of our customers to use. It should run on POST and receive a JSON body with two parameters: id and statuscode.

The logic is simple - I wish to fetch the incident with guid equals id and change its statuscode based on the received value for statuscode.

Code of controller:

public async Task<MyCustomResponse> CloseIncident([FromBody] MyCustomRequest _request)
{
    try 
    {
        // Some logic here to check if both Id and StatusCode exist in _request ...
        
        if(Guid.TryParse(_request.Id, out Guid guid))
        {
            // Construct OData request
            JObject incidentResolution = new JObject();
            incidentResolution.Add("subject", "testing");
            incidentResolution.Add("incidentid@odata.bind", $"/incidents({guid})");
            incidentResolution.Add("timespent", 2); //This is billable time in minutes
            incidentResolution.Add("description", "description");

            JObject parameters = new JObject();
            parameters.Add("IncidentResolution", incidentResolution);

            if (_request.StatusCode == 1)
            {
                parameters.Add("Status", (int)IncidentStatusCode.ProblemSolved);
            }
            else
            {
                parameters.Add("Status", (int)IncidentStatusCode.SomeOtherRejectedStatusCode);
            }

            RegenerateAccess(); // Connect to Microsoft Online

            string urlAPI = "/api/data/v9.1/CloseIncident";

            using (HttpClient client = new HttpClient())
            {
                client.BaseAddress = new Uri(_serviceUrl);
                client.Timeout = new TimeSpan(0, 2, 0);  //2 minutes  
                client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
                client.DefaultRequestHeaders.Add("OData-Version", "4.0");
                //client.DefaultRequestHeaders.Add("Prefer", "return=representation");
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpMethod method = HttpMethod.Post;

                HttpRequestMessage request = new HttpRequestMessage(method, urlAPI);
                request.Content = new StringContent(parameters.ToString(), Encoding.UTF8, "application/json");

                // Set the access token
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _authResult.AccessToken);
                HttpResponseMessage response = await client.SendAsync(request);
                response.EnsureSuccessStatusCode();
                
                return new MyCustomResponse()
                {
                    Status = Status.Success,
                    Message = "..."
                };
            }
            
            return new MyCustomResponse()
            {
                Status = Status.Error,
                Message = "..."
            };
        }
        else throw new Exception("Guid is invalid.");
    }
    catch(Exception ex)
    {
        return new MyCustomResponse() { Status = Status.Error, Message = ex.Message };
    }
}

I'm getting a "Bad Request" from the client.SendAsync line. I think the OData body request is incorrect, but I can't figure out why.


Solution

  • Code looks perfect. I’ll try to add the below header and see the response.

    client.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8");
    

    While trying to debug, if you see any useful error response in exception that will help troubleshooting.