Asp.Net Web Api - Return 404 for IEnumerable <T> Get When null

I am creating an API using the Asp.Net Web Api version. I am trying to pass the correct response code (404) if no results are found.

First Get Version (throws a 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); } 

The second version of Get (the 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 can I pass back 404 if no results are found? I know that I could use a list, but I have a custom csv media type format that only works with IEnumerable types, so I would prefer to stick with this.

+8
c # asp.net-web-api
source share
2 answers

An improved approach is to catch null at the action filter level, define an action filter with a global scope, and throw an 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); } } 

Thus, you do not need to use Any in your action, the code will be simpler:

 public IEnumerable<MyObjectType> Get(int id, string format) { using (db = new DbEntities()) { return db.pr_ApiSelectMyObjectType(store, id, format) .AsEnumerable(); } } 
+25
source share

Probably the easiest way is to simply convert the results to a list, which you can obviously list several times:

 var result = db.pr_ApiSelectMyObjectType(store, id, format).ToList(); if (!result.Any()) { ... } 

Of course, this means materializing the whole request ... but, presumably, you will end up doing this at some point.

+4
source share

All Articles