Stan
Stan

Reputation: 26511

NancyFX - Custom 404 handler overrides every 404 response

I did my custom 404 handler for NancyFX and it works fine but there is a problem. Problem is that it overrides even those requests where I want to send 404 code but with my custom message e.g. "User not found".

Handler

public class NotFoundHandler : IStatusCodeHandler
{
    public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
    {
        if (statusCode == HttpStatusCode.NotFound)
        {
            // How to check here if the url actually exists?
            // I don't want every 404 request to be the same
            // I want to send custom 404 with Response.AsJson(object, HttpStatusCode.NotFound)
            return true;
        }

        return false;
    }

    public void Handle(HttpStatusCode statusCode, NancyContext context)
    {
        context.Response = new TextResponse(JsonConvert.SerializeObject(new { Message = "Resource not found" }, Formatting.Indented))
        {
            StatusCode = statusCode,
            ContentType = "application/json"
        };
    }
}

Problem

Get["/"] = _ =>
{
    // This will not show "User not found", instead it will be overriden and it will show "Resource not found"
    return Response.AsJson(new { Message = "User not found" }, HttpStatusCode.NotFound);
};

Upvotes: 3

Views: 1667

Answers (1)

TheCodeJunkie
TheCodeJunkie

Reputation: 9616

You decide which responses you want to handle in your IStatusCodeHandler implementation(s). Right now you are, only, checking the status code itself, without adding context to it. What you could do (for example) would be to only overwrite context.Response if it doesn't contain a Response that meets certain criterion, such as being of the type JsonResponse

    if(!(context.Response Is JsonResponse))
    {
            context.Response = new TextResponse(JsonConvert.SerializeObject(new { Message = "Resource not found" }, Formatting.Indented))
            {
                StatusCode = statusCode,
                ContentType = "application/json"
            };
    }

Since you have access to the full NancyContext, you also have access to the entire Request and Response (which was returned by a route or something else in the request pipeline). Further you can stick arbitrary metadata in NancyContext.Items if you need even more control.

Hope this helps

Upvotes: 2

Related Questions