Cjmaret
Cjmaret

Reputation: 211

Check if awaited IActionResult returns a 204

The method below returns a 204 if completed successfully, but I'm having trouble checking the status code. It's an IActionResult, in Postman it returns an empty body with a status code of 204.

IActionResult response = await _benchmarkingClient.CheckAndLoadJobDetails(checkAndLoadJobDetailsRequest);

context.Logger.LogLine($"Response StatusCode: {response}");
            
if (response.StatusCode == 204)
 {...}

The above code is unhappy because StatusCode doesn't even exist on response.

If I remove the status code if block, the above returns this error:

"The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true.

This JsonException seems correct, since I don't except any Json. I only need to capture the status code, but have not been able to figure out how to do it.

Edit: This is CheckAndLoadJobDetails:

...
  public async Task<IActionResult> CheckAndLoadJobDetails(CheckAndLoadJobDetailsRequest checkAndLoadJobDetailsRequest, CancellationToken cancel)
    {
        try
        {
            var projectId = checkAndLoadJobDetailsRequest.ProjectId;
            var tenantId = checkAndLoadJobDetailsRequest.TenantId;

            var project = await _apiService.GetLaborApiClient().GetProject(projectId);
            
            var salaryScheduleId = project.ActiveSalaryScheduleId;
            
            var jobDetailsSheet = await _spreadsheetService.GetSpreadsheet(
                $"{SalaryScheduleObjectPrefix}{salaryScheduleId}",
                _config["LcmS3Bucket"], 
                _jobDetailsSheetSpec
            );
            
            if (jobDetailsSheet.Success)
            {
                var loadedJobDetails = await LoadJobDetails(
                    tenantId,
                    project.TenantId,
                    project.ProjectId!,
                    project.ProjectName!,
                    salaryScheduleId,
                    cancel
                );
                
                if (loadedJobDetails)
                { 
                    return new StatusCodeResult(StatusCodes.Status204NoContent);
                }
                return new StatusCodeResult(StatusCodes.Status500InternalServerError);
            }
            throw new BadHttpRequestException(
                $"Job details sheet not found",
                StatusCodes.Status409Conflict
            );
        }
        catch (Exception ex)
        {
            if (ex.GetType() == typeof(BadHttpRequestException))
            {
                throw ex;
            } 
            throw new BadHttpRequestException(
                $"An error occurred: {ex.Message}",
                StatusCodes.Status500InternalServerError
            );
        }
    }

Upvotes: 1

Views: 171

Answers (2)

Kit Grose
Kit Grose

Reputation: 1831

There's a separate interface for IActionResult that happens to have a status code: IStatusCodeActionResult.

Your logic then becomes:

if (response is IStatusCodeActionResult responseWithStatusCode &&  
    responseWithStatusCode.StatusCode == 204)
{...}

…or to be even more explicit:

if (response is IStatusCodeActionResult responseWithStatusCode &&  
    responseWithStatusCode.StatusCode == (int)HttpStatusCode.NoResult)
{...}

Upvotes: 0

jaabh
jaabh

Reputation: 1004

If you know it is returning the correct type and you just need to verify that it is a 204 response, then a cast might work. I say might as in there could be other issues that are not known, especially if you are attempting to manipulate the response when there is no content, 204 response.

Anyway, in order to check the type and the status code of the response, this will work.

var response = await _benchmarkingClient.CheckAndLoadJobDetails(checkAndLoadJobDetailsRequest);

if (response is NoContentResult)
{
    var result = (NoContentResult)response;
    var statusCode = result.StatusCode;
}

NoContentResult is a class that inherits from IActionResult and is used as a No Content 204 response. This will check the type of response and if it is a NoContentResult, will hit the if block. In the if block, cast it to a NoContentResult then grabbing the status code is possible.

Upvotes: 0

Related Questions