Created
October 15, 2014 21:58
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
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));
@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
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.