Si on lui donne l'itinéraire :
{Nom du flux}/{ItemPermalink}
ex : /Blog/Hello-World
Si l'élément n'existe pas, je veux renvoyer un 404. Quelle est la bonne façon de procéder en ASP.NET MVC ?
Si on lui donne l'itinéraire :
{Nom du flux}/{ItemPermalink}
ex : /Blog/Hello-World
Si l'élément n'existe pas, je veux renvoyer un 404. Quelle est la bonne façon de procéder en ASP.NET MVC ?
En prenant des risques (codage de cow-boy ;-)), je suggérerais quelque chose comme ceci :
Contrôleur :
public class HomeController : Controller
{
public ActionResult Index()
{
return new HttpNotFoundResult("This doesn't exist");
}
}
HttpNotFoundResult :
using System;
using System.Net;
using System.Web;
using System.Web.Mvc;
namespace YourNamespaceHere
{
/// <summary>An implementation of <see cref="ActionResult" /> that throws an <see cref="HttpException" />.</summary>
public class HttpNotFoundResult : ActionResult
{
/// <summary>Initializes a new instance of <see cref="HttpNotFoundResult" /> with the specified <paramref name="message"/>.</summary>
/// <param name="message"></param>
public HttpNotFoundResult(String message)
{
this.Message = message;
}
/// <summary>Initializes a new instance of <see cref="HttpNotFoundResult" /> with an empty message.</summary>
public HttpNotFoundResult()
: this(String.Empty) { }
/// <summary>Gets or sets the message that will be passed to the thrown <see cref="HttpException" />.</summary>
public String Message { get; set; }
/// <summary>Overrides the base <see cref="ActionResult.ExecuteResult" /> functionality to throw an <see cref="HttpException" />.</summary>
public override void ExecuteResult(ControllerContext context)
{
throw new HttpException((Int32)HttpStatusCode.NotFound, this.Message);
}
}
}
// By Erik van Brakel, with edits from Daniel Schaffer :)
En utilisant cette approche, vous vous conformez aux normes du framework. Il y a déjà un HttpUnauthorizedResult, donc cela ne ferait qu'étendre le framework aux yeux d'un autre développeur qui maintiendrait votre code plus tard (vous savez, le psychopathe qui sait où vous vivez).
Vous pourriez utiliser reflector pour jeter un coup d'oeil dans l'assemblage pour voir comment le HttpUnauthorizedResult est obtenu, parce que je ne sais pas si cette approche manque quelque chose (elle semble trop simple presque).
J'ai utilisé reflector pour jeter un coup d'oeil au HttpUnauthorizedResult à l'instant. Il semble qu'ils définissent le StatusCode de la réponse à 0x191 (401). Bien que cela fonctionne pour 401, en utilisant 404 comme nouvelle valeur, il semble que je n'obtienne qu'une page blanche dans Firefox. Internet Explorer affiche cependant un 404 par défaut (pas la version ASP.NET). À l'aide de la barre d'outils Webdeveloper, j'ai inspecté les en-têtes dans FF, qui affichent bien une réponse 404 Not Found. Il se peut que je me sois trompé dans la configuration de FF.
Ceci étant dit, je pense que l'approche de Jeff est un bon exemple de KISS. Si vous n'avez pas vraiment besoin de la verbosité de cet exemple, sa méthode fonctionne également très bien.
Nous procédons de la manière suivante ; ce code se trouve dans BaseController
/// <summary>
/// returns our standard page not found view
/// </summary>
protected ViewResult PageNotFound()
{
Response.StatusCode = 404;
return View("PageNotFound");
}
appelé comme ça
public ActionResult ShowUserDetails(int? id)
{
// make sure we have a valid ID
if (!id.HasValue) return PageNotFound();
Le HttpNotFoundResult est une excellente première étape vers ce que j'utilise. Renvoyer un HttpNotFoundResult est une bonne chose. La question qui se pose alors est la suivante : quelle est la suite ?
J'ai créé un filtre d'action appelé HandleNotFoundAttribute qui affiche ensuite une page d'erreur 404. Puisqu'il retourne une vue, vous pouvez créer une vue 404 spéciale par contrôleur, ou laisser le contrôleur utiliser une vue 404 partagée par défaut. Elle sera même appelée lorsqu'un contrôleur n'a pas l'action spécifiée présente, car le framework lance une HttpException avec un code d'état de 404.
public class HandleNotFoundAttribute : ActionFilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
var httpException = filterContext.Exception.GetBaseException() as HttpException;
if (httpException != null && httpException.GetHttpCode() == (int)HttpStatusCode.NotFound)
{
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; // Prevents IIS from intercepting the error and displaying its own content.
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.NotFound;
filterContext.Result = new ViewResult
{
ViewName = "404",
ViewData = filterContext.Controller.ViewData,
TempData = filterContext.Controller.TempData
};
}
}
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.