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;
}
}
@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