Skip to content

Instantly share code, notes, and snippets.

@andygjp
Created October 15, 2014 21:58
Show Gist options
  • Save andygjp/82106facbb0c43f55dc8 to your computer and use it in GitHub Desktop.
Save andygjp/82106facbb0c43f55dc8 to your computer and use it in GitHub Desktop.
A workaround that will recognise when a SingleResult type does not contain any results and replace it with a 404 instead of throwing a SerializationException.
internal class ReplaceNullContentWithNotFoundAttribute : EnableQueryAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
HttpResponseMessage httpResponseMessage = actionExecutedContext.Response;
if (httpResponseMessage.IsSuccessStatusCode && IsContentMissingValue(httpResponseMessage))
{
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.NotFound);
}
}
private static bool IsContentMissingValue(HttpResponseMessage httpResponseMessage)
{
var objectContent = httpResponseMessage.Content as ObjectContent;
if (objectContent == null)
{
return false;
}
var type = GetType(objectContent);
return type == typeof(SingleResult<>) && objectContent.Value == null;
}
private static Type GetType(ObjectContent objectContent)
{
var type = objectContent.ObjectType;
if (type.IsGenericType && !type.IsGenericTypeDefinition)
{
var genericTypeDefinition = type.GetGenericTypeDefinition();
type = genericTypeDefinition;
}
return type;
}
}
@luke-adams
Copy link

Andy - thanks for this; it's a great solution. I found this via a comment you had left on SO and was about to add a question and invite you to answer the question via this comment here, but then I figured someone else might answer it without you being able to get the kudos! I know your comment is there and gave me the solution, but you might want to add a question & answer so it is a little more visible. Thanks again for publishing this. Luke.

@taehtinen
Copy link

Great solution. The official workaround (http://odata.github.io/WebApi/#10-02-work-around-for-singleresult-create) requires including OWin libraries, which seems a bit of an overkill. And using Web API filters is cleaner anyways.

If you wish to produce an OData error response instead of an empty 404 response, use CreateErrorResponse extension method:

actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, 
    HttpWorkerRequest.GetStatusDescription((int)HttpStatusCode.NotFound));

@kolbanis
Copy link

@andygjp I saw your comment on SO and I dont have enough rep there to ask you how to implement your code in a simple get call like this, also @taehtinen

    [EnableQuery]
    public SingleResult<Apple> Get([FromODataUri] int key)
    {
        IQueryable<Apple> result = db.Apples.Where(p => p.AppleId == key);
        return SingleResult.Create(result);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment