2010-05-20 21 views
5

Tengo un problema al crear una vista genérica para representar las páginas NotFound.Crear una vista NotFound genérica en ASP.MVC

La vista está creada y está bien. Necesito saber cómo puedo dirigir al usuario a la vista NotFound en mis controladores y cómo renderizar un "retorno al índice" específico en cada controlador.

Aquí hay un código:

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 Ver

<%@ 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> 

// Controlador pieza de código

// 
    // 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); 
    } 

No estoy seguro de cómo redirigir a una página completamente diferente. ¿Alguien puede darme algún consejo?

Gracias

Respuesta

4

Muy simple, esto es lo que uso y tiene muy pocas dependencias.

Crear una ErrorController.cs de Controladores:

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(); 
     } 
    } 
} 

A continuación, basta con crear una Views\Error\NotFound.aspx con el siguiente contenido, ajustar a medida que se siente en forma (incluyendo su enlace "Volver a casa", voy a incluir un defecto uno para usted):

<%@ 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> 

Después, simplemente en su aplicación MVC Web.config dentro de los <system.web> etiquetas:

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

No se requiere una ruta personalizada si utiliza la ruta general catch-all. Espero que ayude.

+0

Genial, muy simple de hecho! –

0

gracias por su aportación. Pensando mucho aquí, me las arreglé para crear una visión única y NotFound modelo así:

public class NotFoundModel 
{ 
    private string _contentName; 
    private string _notFoundTitle; 
    private string _apologiesMessage; 
    private string _linkText; 
    private string _action; 
    private string _controller; 

    // properties omitted for brevity; 

    public NotFoundModel(string contentName, string notFoundTitle, string apologiesMessage, 
     string linkText, string action, string controller) 
    { 
     this._contentName = contentName; 
     this._notFoundTitle = notFoundTitle; 
     this._apologiesMessage = apologiesMessage; 
     this._linkText = linkText; 
     this._action = action; 
     this._controller = controller; 
    } 

    } 

Mi opinión

<%@ 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> 

    <%= Html.ActionLink(Model.LinkText,Model.Action,Model.Controller) %> 

</asp:Content> 

y este es un ejemplo de cómo lo estoy usando:

public ActionResult Delete(int id) 
    { 
     Term term = termRepository.SingleOrDefault(t => t.TermId == id); 

     if (term == null) 
      return View("NotFound", new NotFoundModel("Termo não encontrado", "Termo não encontrado", 
      "Nos desculpe, mas não conseguimos encontrar o termo solicitado.", "Indíce de Termos", "Index", "Term")); 
     else 
      return View("Delete"); 
    } 

De alguna manera, ASP.MVC también buscó todas las vistas NotFound en carpetas compartidas, por lo que es la única que muestra este con un enlace al correspondiente enlace "Ir al índice del modelo".

Gracias por la ayuda.

Cuestiones relacionadas