0

I'm working on an API and implementing the Onion Architecture, which means my controller is in another project. I'm trying to configure my API to return HATEOAS links for both JSON and XML.

I did a check for the Accept request header to determine this, but when I passed my HttpContext in my controller action body, I get this error:

System.NullReferenceException: Object reference not set to an instance of an object.
mediaType was null.

Here's my ValidateMediaTypeAttribute class:

public class ValidateMediaTypeAttribute : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        var acceptHeaderPresent = context.HttpContext.Request.Headers.ContainsKey("Accept");

        if (!acceptHeaderPresent)
        {
            context.Result = new BadRequestObjectResult($"Accept header is missing.");
            return;
        }

        var mediaType = context.HttpContext.Request.Headers["Accept"].FirstOrDefault();

        if (!MediaTypeHeaderValue.TryParse(mediaType, out MediaTypeHeaderValue? outMediaType))
        {
            context.Result = new BadRequestObjectResult($"Media type not present. Please add Accept header with the required media type.");
            return;
        }

        context.HttpContext.Items.Add("AcceptHeaderMediaType", outMediaType);
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
    }
}

And here's my controller

public async Task<IActionResult> GetEmployeesForCompany(Guid companyId, [FromQuery] EmployeeParameters employeeParameters)
{
    var linkParams = new LinkParameters(employeeParameters, _httpContextAccessor.HttpContext);
    var pagedResult = await _service.EmployeeService.GetEmployeesAsync(companyId, linkParams, trackChanges: false);
    Response.Headers.Add("X-Pagination", JsonSerializer.Serialize(pagedResult.metaData));

    return pagedResult.linkResponse.HasLinks ? Ok(pagedResult.linkResponse.LinkedEntities) : Ok(pagedResult.linkResponse.ShapedEntities);
}

This is my TryGenerateLinks method:

public LinkResponse TryGenerateLinks(IEnumerable<EmployeeDto> employeesDto, string fields, Guid companyId, HttpContext httpContext)
{
    var shapedEmployees = ShapeData(employeesDto, fields);

    if (ShouldGenerateLinks(httpContext))
        return ReturnLinkedEmployees(employeesDto, fields, companyId, httpContext, shapedEmployees);

    return ReturnShapedEmployees(shapedEmployees);
}

private List<Entity> ShapeData(IEnumerable<EmployeeDto> employeesDto, string fields) =>
    _dataShaper.ShapedData(employeesDto, fields).Select(e => e.Entity).ToList();

private bool ShouldGenerateLinks(HttpContext httpContext)
{
    var mediaType = (MediaTypeHeaderValue)httpContext.Items["AcceptHeaderMediaType"]; // Error occurs here

    return mediaType.SubTypeWithoutSuffix.EndsWith("hateoas", StringComparison.InvariantCultureIgnoreCase)
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
GODMAN
  • 11
  • 2
  • 1
    Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Sir Rufo May 21 '23 at 02:42
  • Maybe you wanted to put your into ``OnActionExecuting`` not ``OnActionExecuted``! – sa-es-ir May 21 '23 at 05:30
  • @sa-es-ir thank you so much i automatically implemented the interface and thoought the on executing class will automatically come before its successors – GODMAN May 21 '23 at 12:17

0 Answers0