I am creating an API using the release version of Asp.Net Web Api. I am trying to pass back the correct response code (404) if no results are found.
First Get Version (throws multiple enumeration error):
public IEnumerable<MyObjectType> Get(int id, string format)
{
var db = new DbEntities();
var result = db.pr_ApiSelectMyObjectType(store, id, format).AsEnumerable();
if (result.Any())
{
return result;
}
var response = new HttpResponseMessage(HttpStatusCode.NotFound)
{ Content = new StringContent("Unable to find any results") };
throw new HttpResponseException(response);
}
Second Get Version (result is never null, so it always returns 200):
public IEnumerable<MyObject> Get(int id, string format)
{
var db = new DbEntities();
var result = db.pr_ApiSelectMyObjectType(store, id, format);
if (result == null)
{
var response = new HttpResponseMessage(HttpStatusCode.NoContent)
{ Content = new StringContent("Unable to find any results") };
throw new HttpResponseException(response);
}
return result.AsEnumerable();
}
How do I pass back a 404 if no results are found? I know I could use a list, but I have a custom csv media type formatter that only works with IEnumerable types, so I would prefer to stick with that.
Better approach is to catch null
at action filter level, define an action filter with global scope, and throw exception 404 from this:
public class NullFilter : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var response = actionExecutedContext.Response;
object responseValue;
bool hasContent = response.TryGetContentValue(out responseValue);
if (!hasContent)
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
With this way, you don't need to use Any
in your action, code would be simpler:
public IEnumerable<MyObjectType> Get(int id, string format)
{
using (db = new DbEntities())
{
return db.pr_ApiSelectMyObjectType(store, id, format)
.AsEnumerable();
}
}
It's probably simplest to just convert the results to a list, which can obviously be enumerated multiple times:
var result = db.pr_ApiSelectMyObjectType(store, id, format).ToList();
if (!result.Any())
{
...
}
Of course that means materializing the whole query... but presumably you'd end up doing that anyway at some point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With