If a route throws an error, and the user tries to query it, you will lose the error and get an error about how the query is invalid.
using:
"Microsoft.AspNetCore.OData" Version="7.1.0"
"Microsoft.OData.Core" Version="7.5.4"
"Microsoft.AspnetCore.App" Version=2.24"
Create a controller like so:
public class Always400Controller : ODataController
{
[EnableQuery]
public IHttpActionResult Get()
{
return BadRequest(new ODataError{Message="This route gives a 400"});
}
}
Now hit it with your web browser
/Always400?$top=1
You should get a 400 error with the following output
{"error":{"code":"","message":"This route gives a 400"}}
You get a 500 error with the following output
{"error":{"code":"","message":"The query specified in the URI is not valid. The requested resource is not a collection. Query options $filter, $orderby, $count, $skip, and $top can be applied only on collections.","details":[],"innererror":{"message":"The requested resource is not a collection. Query options $filter, $orderby, $count, $skip, and $top can be applied only on collections.","type":"Microsoft.OData.ODataException","stacktrace":" at Microsoft.AspNet.OData.EnableQueryAttribute.ValidateSelectExpandOnly(ODataQueryOptions queryOptions)rn at Microsoft.AspNet.OData.EnableQueryAttribute.ExecuteQuery(Object responseValue, IQueryable singleResultCollection, IWebApiActionDescriptor actionDescriptor, Func
2 modelFunction, IWebApiRequestMessage request, Func2 createQueryOptionFunction)rn at Microsoft.AspNet.OData.EnableQueryAttribute.OnActionExecuted(Object responseValue, IQueryable singleResultCollection, IWebApiActionDescriptor actionDescriptor, IWebApiRequestMessage request, Func2 modelFunction, Func2 createQueryOptionFunction, Action1 createResponseAction, Action3 createErrorAction)"}}}
Investigating the error seems to be here
https://github.com/OData/WebApi/blob/3b1ecc572088ff1c1abc5147b29191cfe3afbe58/src/Microsoft.AspNetCore.OData/EnableQueryAttribute.cs#L75-L76
Basically, BadRequestObjectResult and other ObjectResult errors do not inherit from StatusCodeResult.
The solution would be to use IStatusCodeActionResult like so::
var statusCodeResult = actionExecutedContext.Result as IStatusCodeActionResult;
if (statusCodeResult is null || !statusCodeResult.StatusCode.HasValue
|| IsSuccessStatusCode(statusCodeResult.StatusCode.Value))
After staring at the code, I found this workaround, but I hate it.
if(errorCondition)
{
HttpContext.Response.Status = 400;
return new BadRequestObjectResult(...);
}
This is also broken in 7.2 still. It's disappointing that very little was fixed.
Most helpful comment
Investigating the error seems to be here
https://github.com/OData/WebApi/blob/3b1ecc572088ff1c1abc5147b29191cfe3afbe58/src/Microsoft.AspNetCore.OData/EnableQueryAttribute.cs#L75-L76
Basically,
BadRequestObjectResultand otherObjectResulterrors do not inherit fromStatusCodeResult.The solution would be to use
IStatusCodeActionResultlike so::After staring at the code, I found this workaround, but I hate it.