0

For example, we have simple action method to show any book with proper id:

public ActionResult GetBook(int id) // id = 123456789
    {
        var book = dataManager.Books.GetBookById(id); // == null
        logger.Info("Getting book with id " + book.Id);
        return View(book);
    }

If id parameter is not valid we get 500 error because there is no book with that id.

We have to handle this situation manually if we need to throw 404 error, like this:

if (book == null)
        {
            return HttpNotFound();
        }

Is it possible to switch 500-error to 404-error for all action methods somewhere in web-application (custom filter, request pipeline)?

Sam Alekseev
  • 2,281
  • 2
  • 19
  • 28

2 Answers2

3

Technically you could, by installing an error handler, rewrite any 500 Internal Server Error to a 404 Not Found in Application_Error() as explained in ASP.NET MVC 5 error handling.

However, you seem to want to let your code throw a NullReferenceException on a null book in book.Id, and turn that exception into a 404.

You really shouldn't be doing that in this case, because this will hide programming errors, because you will miss the exceptions where this happened unintentionally.

So: just do this explicitly where you do expect a null. The code you showed is exactly what you need:

if (book == null)
{
    return HttpNotFound();
}
Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • My purpose is to show end user 404 error if he requests non existent entity but to show 500 error on any other case. I cant figure out is it possible to program generic version of this checking somewhere outside of controller class (and not to copy this code in every action method). – Sam Alekseev Feb 16 '17 at 09:32
  • There is no way for C# to know whether `book.Id` is meant to throw a "entity not found" exception which you can turn into a 404, and for `someOtherObject.DoSomething()` to throw a genuine `NullReferenceException` which you expose as a 500. If you have a lot of methods that look the same, look into patterns to reduce the duplication. That's a whole nother question though. – CodeCaster Feb 16 '17 at 09:34
  • Thank you! I think the same thing. I use dependency injector, EF code-first technique, all my entities derived from EntityBase class. So i can upcast any entity to base in my web-application when i get it from database. – Sam Alekseev Feb 16 '17 at 09:44
0

I found this helpful Bulk 301 Redirect

I test then throw a 302

try
{
  ------
}
catch
{
    throw new HttpException(302, "not found");
}

Catch the exception in the Global.asax and look up a redirect csv file

protected void Application_Error()
    {
        Exception exception = Server.GetLastError();

        Response.Clear();
        Server.ClearError();

        HttpException ex = exception as HttpException;

        if (ex.GetHttpCode() == 404 || ex.GetHttpCode() == 302 || ex.GetHttpCode() == 500)
            {
                Redirect code in the link!
            }
    }