Description
When executing an API with [EnableQuery]
, an exception will be raised if OData argument validation fails, even if the controller returned a non-successful response (like 404) where we don't expect the OData argument validation to succeed.
Assemblies affected
- Microsoft.AspNetCore.OData, Version=7.0.1.20718
- Microsoft.AspNetCore.OData, Version=7.3.0.0
Reproduce steps
Take the following simple aspnetcore odata controller:
using System.Net;
using System.Threading.Tasks;
using AspNetCore.Mvc;
using Microsoft.AspNet.OData;
using Microsoft.AspNet.OData.Query;
using Microsoft.AspNet.OData.Routing;
public class RecordController : ODataController
{
[HttpGet]
[ODataRoute("records/{id}")]
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.Select | AllowedQueryOptions.Expand)]
public async Task<IActionResult> GetRecord(string id)
{
return this.StatusCode((int)HttpStatusCode.NotFound, new { Error = new { Code = nameof(HttpStatusCode.NotFound), Message = ErrorMessages.NotFoundMessage } });
}
}
Execute query:
GET records/{id}?$expand=myProperty
Expected result
Since we returned a non-success status code, I would expect the error response to get passed through.
Actual result
EnableQueryAttribute attempts to validate the $expand value and it can't find myProperty since that doesn't exist in the error response. Thus a BadRequest is returned instead of the error I expected.
Additional detail
The EnableQueryAttribute implementation checks HttpContext.Response for its status code, but nothing in the AspNetCore request pipeline sets this by default. Instead the response is on ActionExecutedContext.Result.
You can work around the issue by setting Response.StatusCode from the controller before returning, but this seems like it should be fixed in either EnableQueryAttribute or the AspNetCore request pipeline.