Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a generic NotFound View in ASP.MVC

Tags:

c#

asp.net-mvc

I'm having a problem to create a generic View to represent NotFound pages.

The view is created and it's fine. I need to know how i can direct the user to the NotFound view in my Controllers and how to render a specific "Return to Index" in each controller.

Here is some code:

public class NotFoundModel
{
    private string _contentName;
    private string _notFoundTitle;
    private string _apologiesMessage;

    public string ContentName { get; private set; }
    public string NotFoundTitle { get; private set; }
    public string ApologiesMessage { get; private set; }

    public NotFoundModel(string contentName, string notFoundTitle, string apologiesMessage)
    {
        this._contentName = contentName;
        this._notFoundTitle = notFoundTitle;
        this._apologiesMessage = apologiesMessage;
    }

    }

// NotFound View

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Geographika.Models.NotFoundModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    <%= Html.Encode(Model.ContentName) %>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2><%= Html.Encode(Model.NotFoundTitle) %></h2>

    <p><%= Html.Encode(Model.ApologiesMessage) %></p>

    <!-- How can i render here a specific "BackToIndexView", but that it's not bound to
    my NotFoundModel? -->

</asp:Content>

// Controller piece of code

    //
    // GET: /Term/Details/2
    public ActionResult Details(int id)
    {
        Term term = termRepository.SingleOrDefault(t => t.TermId == id);

        if (term == null)
            return View("NotFound"); // how can i return the specific view that its not bound to Term Model?

            // the idea here would be something like:
            // return View("NotFound",new NotFoundModel("a","b","c"));

        else
            return View("Details", term);
    }

I'm not sure how to redirect to a whole different page. Can anyone give me any pointers?

Thanks

like image 768
George Silva Avatar asked Oct 15 '22 05:10

George Silva


1 Answers

Very simple, this is what I use and has very little dependencies.

Create an ErrorController.cs in Controllers:

public class ErrorController : Controller
    {
        public ErrorController()
        {
            //_logger = logger; // log here if you had a logger!
        }

        /// <summary>
        /// This is fired when the site gets a bad URL
        /// </summary>
        /// <returns></returns>
        public ActionResult NotFound()
        {
            // log here, perhaps you want to know when a user reaches a 404?
            return View();
        }
    }
}

Then simply create a Views\Error\NotFound.aspx with the following contents, tweak as you feel fit (including your "Back to home" link, I'll include a default one for you):

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Oops - No content here!
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>404 Error - Can't find that page</h2>

    <p>Sorry, we cannot find the page you are looking for</p>

</asp:Content>

Then simply in your MVC app Web.config within the <system.web> tags:

<customErrors mode="Off" defaultRedirect="/error/problem">
    <error statusCode="404" redirect="/error/notfound"/>
</customErrors>

No custom route required either if you use the standard catch-all route. Hope that helps.

like image 172
GONeale Avatar answered Oct 18 '22 23:10

GONeale