J'utilise RC2
Utilisation du routage URL:
routes.MapRoute(
"Error",
"{*url}",
new { controller = "Errors", action = "NotFound" } // 404s
);
Ce qui précède semble prendre en charge des requêtes comme celle-ci (en supposant que les tables de routage par défaut sont configurées par le projet MVC initial): "/ blah / blah / blah / blah"
Substitution de HandleUnknownAction () dans le contrôleur lui-même:
// 404s - handle here (bad action requested
protected override void HandleUnknownAction(string actionName) {
ViewData["actionName"] = actionName;
View("NotFound").ExecuteResult(this.ControllerContext);
}
Cependant, les stratégies précédentes ne traitent pas une demande à un contrôleur incorrect / inconnu. Par exemple, je n'ai pas de "/ IDoNotExist", si je le demande, j'obtiens la page générique 404 du serveur Web et pas ma 404 si j'utilise routage + remplacement.
Enfin, ma question est: existe-t-il un moyen d'attraper ce type de demande en utilisant une route ou autre chose dans le framework MVC lui-même?
OU devrais-je utiliser par défaut Web.Config customErrors comme gestionnaire 404 et oublier tout cela? Je suppose que si je choisis CustomErrors, je devrai stocker la page générique 404 en dehors de / Views en raison des restrictions Web.Config sur l'accès direct.
Réponses:
Le code est extrait de http://blogs.microsoft.co.il/blogs/shay/archive/2009/03/06/real-world-error-hadnling-in-asp-net-mvc-rc2.aspx et fonctionne dans ASP.net MVC 1.0 également
Voici comment je gère les exceptions http:
la source
Exigences pour 404
Voici mes exigences pour une solution 404 et ci-dessous, je montre comment je l'implémente:
Solution
Je pense que vous devriez enregistrer
Application_Error
dans Global.asax pour des choses plus élevées, comme les exceptions non gérées et la journalisation (comme le montre la réponse de Shay Jacoby ), mais pas la gestion 404. C'est pourquoi ma suggestion garde les 404 choses hors du fichier Global.asax.Étape 1: avoir une place commune pour la logique d'erreur 404
C'est une bonne idée de maintenabilité. Utilisez un ErrorController pour que les améliorations futures de votre page 404 bien conçue puissent s'adapter facilement. Assurez-vous également que votre réponse contient le code 404 !
Étape 2: utilisez une classe de contrôleur de base pour pouvoir invoquer facilement votre action 404 personnalisée et câbler
HandleUnknownAction
Les 404 dans ASP.NET MVC doivent être capturés à plusieurs endroits. Le premier est
HandleUnknownAction
.La
InvokeHttp404
méthode crée un lieu commun pour le réacheminement vers laErrorController
et notre nouvelleHttp404
action. Pensez SEC !Étape 3: utilisez l'injection de dépendance dans votre usine de contrôleurs et connectez 404 HttpExceptions
Comme ça (il ne doit pas nécessairement s'agir de StructureMap):
Exemple MVC1.0:
Exemple MVC2.0:
Je pense qu'il vaut mieux attraper les erreurs plus près de leur origine. C'est pourquoi je préfère ce qui précède au
Application_Error
gestionnaire.C'est le deuxième endroit pour attraper 404s.
Étape 4: ajoutez une route NotFound à Global.asax pour les URL qui ne sont pas analysées dans votre application
Cette route devrait indiquer notre
Http404
action. Remarquez que leurl
paramètre sera une URL relative, car le moteur de routage supprime la partie de domaine ici? C'est pourquoi nous avons toute cette logique d'URL conditionnelle à l'étape 1.C'est le troisième et dernier endroit pour attraper 404 dans une application MVC que vous n'invoquez pas vous-même. Si vous n'attrapez pas d'itinéraires inégalés ici, MVC passera le problème à ASP.NET (Global.asax) et vous ne le voulez pas vraiment dans cette situation.
Étape 5: Enfin, appelez les 404 lorsque votre application ne trouve rien
Comme lorsqu'un mauvais ID est soumis à mon contrôleur de prêts (dérive de
MyController
):Ce serait bien si tout cela pouvait être connecté en moins d'endroits avec moins de code mais je pense que cette solution est plus maintenable, plus testable et assez pragmatique.
Merci pour le retour jusqu'à présent. J'adorerais en avoir plus.
REMARQUE: cela a été modifié de manière significative à partir de ma réponse d'origine, mais le but / les exigences sont les mêmes - c'est pourquoi je n'ai pas ajouté de nouvelle réponse
la source
customErrors
section du web.config définit les pages de redirection statique qui sont gérées à un niveau élevé dans aspnet sinon IIS. Ce n'est pas ce que je voulais car j'avais besoin que le résultat soit MVC Views (donc je peux avoir des données dedans, etc.). Je ne dirais pas catégoriquement que "customErrors
est obsolète dans MVC" mais pour moi et cette solution 404, ils le sont certainement.ObjectFactory.GetInstance
à MVC3 à laDependencyResolver.Current.GetService
place, donc c'est plus générique. J'utilise Ninject.ASP.NET MVC ne prend pas très bien en charge les pages 404 personnalisées. Usine de contrôleur personnalisée, itinéraire fourre-tout, classe de contrôleur de base avec
HandleUnknownAction
- argh!Les pages d'erreur personnalisées IIS sont une meilleure alternative jusqu'à présent:
web.config
ErrorController
Exemple de projet
la source
customErrors mode="On"
avec leHandleErrorAttribute
fonctionnel. Les pages d'erreur personnalisées pour les exceptions non gérées dans les actions du contrôleur ne sont plus servies.Réponse rapide / TL; DR
Pour les paresseux:
Supprimez ensuite cette ligne de
global.asax
Et ce n'est que pour IIS7 + et IIS Express.
Si vous utilisez Cassini ... eh bien ... euh ... euh ... maladroit ...
Réponse longue et expliquée
Je sais que cela a été répondu. Mais la réponse est VRAIMENT SIMPLE (bravo à David Fowler et Damian Edwards pour avoir vraiment répondu à cela).
Il n'est pas nécessaire de faire quoi que ce soit de personnalisé .
Car
ASP.NET MVC3
, tous les morceaux sont là.Étape 1 -> Mettez à jour votre web.config en DEUX spots.
et
Maintenant, prenez bien note des ITINÉRAIRES que j'ai décidé d'utiliser. Vous pouvez utiliser n'importe quoi, mais mes itinéraires sont
/NotFound
<- pour un 404 introuvable, page d'erreur./ServerError
<- pour toute autre erreur, incluez les erreurs qui se produisent dans mon code. il s'agit d'une erreur de 500 serveurs internesVoyez comment la première section
<system.web>
ne contient qu'une seule entrée personnalisée? L'statusCode="404"
entrée? Je n'ai répertorié qu'un seul code d'état, car toutes les autres erreurs, y compris500 Server Error
(c.-à-d. Ces erreurs embêtantes qui se produisent lorsque votre code a un bogue et plante la demande de l'utilisateur) .. toutes les autres erreurs sont gérées par le paramètredefaultRedirect="/ServerError"
.. qui dit , si vous n'êtes pas une page 404 introuvable, alors veuillez vous rendre sur l'itinéraire/ServerError
.D'accord. c'est à l'écart .. maintenant à mes itinéraires répertoriés dans
global.asax
Étape 2 - Création des itinéraires dans Global.asax
Voici ma section complète de l'itinéraire ..
Cela répertorie deux routes ignorées ->
axd's
etfavicons
(ooo! Bonus ignore route, pour vous!) Ensuite (et la commande est IMPERATIVE ICI), j'ai mes deux routes explicites de gestion des erreurs .. suivies de toutes les autres routes. Dans ce cas, celui par défaut. Bien sûr, j'en ai plus, mais c'est spécial pour mon site Web. Assurez-vous simplement que les routes d'erreur sont en haut de la liste. L'ordre est impératif .Enfin, pendant que nous sommes à l'intérieur de notre
global.asax
fichier, nous n'enregistrons PAS globalement l'attribut HandleError. Non, non, non monsieur. Nadda. Nan. Nien. Négatif. Noooooooooo ...Supprimer cette ligne de
global.asax
Étape 3 - Créez le contrôleur avec les méthodes d'action
Maintenant .. nous ajoutons un contrôleur avec deux méthodes d'action ...
Ok, voyons ça. Tout d'abord, il n'y a AUCUN
[HandleError]
attribut ici. Pourquoi? Parce que leASP.NET
framework intégré gère déjà les erreurs ET nous avons spécifié toute la merde que nous devons faire pour gérer une erreur :) C'est dans cette méthode!Ensuite, j'ai les deux méthodes d'action. Rien de difficile là-bas. Si vous souhaitez afficher des informations d'exception, vous pouvez les utiliser
Server.GetLastError()
pour obtenir ces informations.Bonus WTF: Oui, j'ai fait une troisième méthode d'action, pour tester la gestion des erreurs.
Étape 4 - Créez les vues
Et enfin, créez deux vues. Mettez-les dans la vue normale, pour ce contrôleur.
Commentaires bonus
Application_Error(object sender, EventArgs e)
Et ça, mes amis, ça devrait être ça.
Maintenant, félicitations pour avoir lu autant et avoir une licorne comme prix!
la source
?aspxerrorpath=/er/not/found
avoir dans les URL.J'ai beaucoup étudié la façon de gérer correctement les 404 dans MVC (en particulier MVC3) , et cela, à , est la meilleure solution que j'ai trouvée:
Dans global.asax:
ErrorsController:
(Optionnel)
Explication:
AFAIK, il y a 6 cas différents qu'une application ASP.NET MVC3 peut générer 404s.
(Généré automatiquement par ASP.NET Framework :)
(1) Une URL ne trouve pas de correspondance dans la table de routage.
(Généré automatiquement par ASP.NET MVC Framework :)
(2) Une URL trouve une correspondance dans la table de routage, mais spécifie un contrôleur inexistant.
(3) Une URL trouve une correspondance dans la table de routage, mais spécifie une action inexistante.
(Généré manuellement :)
(4) Une action renvoie un HttpNotFoundResult en utilisant la méthode HttpNotFound ().
(5) Une action lève une HttpException avec le code d'état 404.
(6) Une action modifie manuellement la propriété Response.StatusCode en 404.
Normalement, vous souhaitez atteindre 3 objectifs:
(1) Afficher une page d'erreur 404 personnalisée à l'utilisateur.
(2) Conserver le code d'état 404 sur la réponse du client (particulièrement important pour le référencement).
(3) Envoyez la réponse directement, sans impliquer de redirection 302.
Il existe différentes manières d’effectuer cette opération:
(1)
Problèmes avec cette solution:
(2)
Problèmes avec cette solution:
(3)
Problèmes avec cette solution:
(4)
et
Problèmes avec cette solution:
Les gens qui ont déjà rencontré des problèmes avec cela ont même essayé de créer leurs propres bibliothèques (voir http://aboutcode.net/2011/02/26/handling-not-found-with-asp-net-mvc3.html ). Mais la solution précédente semble couvrir tous les cas sans la complexité de l'utilisation d'une bibliothèque externe.
la source
public ActionResult NotFound() {}
dans votre ErrorsController. Pouvez-vous également expliquer à quoi_NotFound
ressemblerait votre partiel pour les demandes AJAX?MissingMethodException: Cannot create an abstract class
sur la ligne.c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
Des idées?J'aime vraiment la solution cottsaks et je pense que son explication est très claire. mon seul ajout était de modifier l'étape 2 comme suit
Fondamentalement, cela empêche les URL contenant des actions non valides ET les contrôleurs de déclencher la routine d'exception deux fois. par exemple pour les URL telles que asdfsdf / dfgdfgd
la source
La seule façon de faire fonctionner la méthode de @ cottsak pour des contrôleurs non valides était de modifier la demande d'itinéraire existante dans CustomControllerFactory, comme ceci:
Je dois mentionner que j'utilise MVC 2.0.
la source
Voici une autre méthode utilisant des outils MVC que vous pouvez gérer les demandes de mauvais noms de contrôleur, de mauvais noms de route et tout autre critère que vous jugez approprié à l'intérieur d'une méthode Action. Personnellement, je préfère éviter autant de paramètres web.config que possible, car ils font la redirection 302/200 et ne prennent pas en charge ResponseRewrite (
Server.Transfer
) en utilisant les vues Razor. Je préfère renvoyer un 404 avec une page d'erreur personnalisée pour des raisons de référencement.Une partie de cela est une nouvelle approche de la technique de cottsak ci-dessus.
Cette solution utilise également des paramètres web.config minimaux favorisant les filtres d'erreur MVC 3 à la place.
Usage
Il suffit de lever une HttpException à partir d'une action ou d'un ActionFilterAttribute personnalisé.
Étape 1
Ajoutez le paramètre suivant à votre web.config. Cela est nécessaire pour utiliser HandleErrorAttribute de MVC.
Étape 2
Ajoutez un HandleHttpErrorAttribute personnalisé similaire au HandleErrorAttribute du framework MVC, sauf pour les erreurs HTTP:
Étape 3
Ajoutez des filtres à GlobalFilterCollection (
GlobalFilters.Filters
) dansGlobal.asax
. Cet exemple achemine toutes les erreurs InternalServerError (500) vers la vue partagée Error (Views/Shared/Error.vbhtml
). Les erreurs NotFound (404) seront également envoyées à ErrorHttp404.vbhtml dans les vues partagées. J'ai ajouté une erreur 401 ici pour vous montrer comment cela peut être étendu pour des codes d'erreur HTTP supplémentaires. Notez que ces vues doivent être partagées et qu'elles utilisent toutes l'System.Web.Mvc.HandleErrorInfo
objet comme modèle.Étape 4
Créez une classe de contrôleur de base et héritez-en dans vos contrôleurs. Cette étape nous permet de gérer les noms d'actions inconnus et de déclencher l'erreur HTTP 404 à notre HandleHttpErrorAttribute.
Étape 5
Créez un remplacement ControllerFactory et remplacez-le dans votre fichier Global.asax dans Application_Start. Cette étape nous permet de lever l'exception HTTP 404 lorsqu'un nom de contrôleur non valide a été spécifié.
Étape 6
Incluez un itinéraire spécial dans votre RoutTable.Routes pour l'action BaseController Unknown. Cela nous aidera à générer un 404 dans le cas où un utilisateur accède à un contrôleur inconnu ou à une action inconnue.
Sommaire
Cet exemple montre comment utiliser le framework MVC pour renvoyer 404 codes d'erreur Http au navigateur sans redirection à l'aide d'attributs de filtre et de vues d'erreur partagées. Il montre également l'affichage de la même page d'erreur personnalisée lorsque des noms de contrôleur et des noms d'action non valides sont spécifiés.
J'ajouterai une capture d'écran d'un nom de contrôleur non valide, d'un nom d'action et d'un 404 personnalisé généré à partir de l'action Home / TriggerNotFound si j'obtiens suffisamment de votes pour en poster un =). Fiddler renvoie un message 404 lorsque j'accède aux URL suivantes à l'aide de cette solution:
le post de cottsak ci-dessus et ces articles étaient de bonnes références.
la source
The IControllerFactory 'aaa.bbb.CustomControllerFactory' did not return a controller for the name '123'.
- des idées pourquoi j'aurais ça?Ma solution raccourcie qui fonctionne avec les zones non contrôlées, les contrôleurs et les actions:
Créez une vue 404.cshtml.
Créez une classe de base pour vos contrôleurs:
Créez une fabrique de contrôleurs personnalisés renvoyant votre contrôleur de base comme solution de rechange:
Ajoutez à
Application_Start()
la ligne suivante:la source
Dans MVC4 WebAPI 404 peut être géré de la manière suivante,
COURS APICONTROLLER
CONTRÔLEUR À DOMICILE
VUE
GLOBAL
RÉSULTATS
la source
Essayez NotFoundMVC sur nuget. Cela fonctionne, aucune configuration.
la source
http://localhost/Views/Shared/NotFound.cshtml
n'entraîne pas une page 404 personnalisée.Ma solution, au cas où quelqu'un la trouverait utile.
Dans Web.config:
Dans
Controllers/ErrorController.cs
:Ajoutez un
PageNotFound.cshtml
dans leShared
dossier, et c'est tout.la source
model.RequestedUrl = Request.Url.OriginalString.Contains(url) & Request.Url.OriginalString != url ? Request.Url.OriginalString : url;
et nonmodel.RequestedUrl = Request.Url.OriginalString.Contains(url) && Request.Url.OriginalString != url ? Request.Url.OriginalString : url;
(& au lieu de &&)?Il me semble que la
CustomErrors
configuration standard devrait tout de même fonctionner , carServer.Transfer
il semble que l'implémentation interne deResponseRewrite
ne soit pas compatible avec MVC.Cela me semble être un trou de fonctionnalité flagrant, j'ai donc décidé de réimplémenter cette fonctionnalité à l'aide d'un module HTTP. La solution ci-dessous vous permet de gérer n'importe quel code d'état HTTP (y compris 404) en redirigeant vers n'importe quelle route MVC valide comme vous le feriez normalement.
Cela a été testé sur les plates-formes suivantes;
Avantages
La solution
Usage
Incluez-le comme module HTTP final dans votre web.config
Pour ceux d'entre vous qui font attention, vous remarquerez qu'en mode Pipeline intégré, cela répondra toujours avec HTTP 200 en raison de la façon dont cela
Server.TransferRequest
fonctionne. Pour renvoyer le code d'erreur approprié, j'utilise le contrôleur d'erreur suivant.la source
Traiter les erreurs dans ASP.NET MVC est juste une douleur dans le cul. J'ai essayé beaucoup de suggestions sur cette page et sur d'autres questions et sites et rien ne fonctionne bien. Une suggestion a été de gérer les erreurs sur web.config à l' intérieur de system.webserver mais cela ne fait que renvoyer des pages blanches .
Mon objectif en proposant cette solution était de:
Voici ma solution.
1 .Ajoutez ce qui suit à la section system.web
Ce qui précède gère toutes les URL non gérées par routes.config et les exceptions non gérées, en particulier celles rencontrées sur les vues. Remarquez que j'ai utilisé aspx pas html . C'est pour que je puisse ajouter un code de réponse sur le code derrière.
2 . Créez un dossier appelé Erreur (ou ce que vous préférez) à la racine de votre projet et ajoutez les deux formulaires Web. Voici ma page 404;
Et sur le code derrière j'ai mis le code de réponse
Faites de même pour la page 500
3 Pour gérer les erreurs dans les contrôleurs. Il y a plusieurs façons de le faire. C'est ce qui a fonctionné pour moi. Tous mes contrôleurs héritent d'un contrôleur de base. Dans le contrôleur de base, j'ai les méthodes suivantes
4. Ajoutez le CustomError.cshtml à votre dossier Vues partagées . Ci-dessous est le mien;
Maintenant, dans votre contrôleur d'application, vous pouvez faire quelque chose comme ça;
Maintenant pour la mise en garde . Il ne gère pas les erreurs de fichiers statiques. Donc, si vous avez un itinéraire tel que example.com/widgets et que l'utilisateur le change en example.com/widgets.html , ils obtiendront la page d'erreur par défaut IIS, vous devrez donc gérer les erreurs de niveau IIS d'une autre manière.
la source
Publier une réponse car mon commentaire était trop long ...
C'est à la fois un commentaire et des questions au post licorne / réponse:
https://stackoverflow.com/a/7499406/687549
Je préfère cette réponse aux autres pour sa simplicité et le fait qu'apparemment certaines personnes chez Microsoft ont été consultées. J'ai cependant trois questions et si elles peuvent être répondues, j'appellerai cette réponse le Saint Graal de toutes les réponses d'erreur 404/500 sur les interwebs pour une application ASP.NET MVC (x).
@ Pure.Krome
Pouvez-vous mettre à jour votre réponse avec les éléments SEO des commentaires soulignés par GWB (il n'y a jamais eu de mention de cela dans votre réponse) -
<customErrors mode="On" redirectMode="ResponseRewrite">
et<httpErrors errorMode="Custom" existingResponse="Replace">
?Pouvez-vous demander à vos amis de l'équipe ASP.NET s'il est correct de le faire comme ça - ce serait bien d'avoir une confirmation - peut-être que c'est un grand non-non à changer
redirectMode
etexistingResponse
de cette façon être en mesure de bien jouer avec le référencement?!Pouvez - vous ajouter quelques précisions entourant ce genre de choses (
customErrors redirectMode="ResponseRewrite"
,customErrors redirectMode="ResponseRedirect"
,httpErrors errorMode="Custom" existingResponse="Replace"
, RETIRERcustomErrors
COMPLÈTEMENT comme quelqu'un a suggéré) après avoir parlé à vos amis chez Microsoft?Comme je le disais; ce serait supernice si nous pouvions rendre votre réponse plus complète car cela semble être une question assez populaire avec 54 000+ vues.
Mise à jour : la réponse Licorne fait un 302 trouvé et un 200 OK et ne peut pas être modifiée pour ne renvoyer que 404 en utilisant un itinéraire. Ce doit être un fichier physique qui n'est pas très MVC: ish. Passons donc à une autre solution. Dommage car cela semblait être le MVC ultime: c'est la réponse jusqu'ici.
la source
Ajout de ma solution, qui est presque identique à celle d'Herman Kan, avec une petite ride pour lui permettre de fonctionner pour mon projet.
Créez un contrôleur d'erreur personnalisé:
Créez ensuite une fabrique de contrôleurs personnalisés:
Enfin, ajoutez un remplacement au contrôleur d'erreur personnalisé:
Et c'est tout. Pas besoin de modifications de Web.config.
la source
1) Créez une classe de contrôleur abstraite.
2) Faites l'héritage de cette classe abstraite dans tous vos contrôleurs
3) Et ajoutez une vue nommée "NotFound" dans votre dossier View-Shared.
la source
J'ai parcouru la plupart des solutions publiées sur ce fil. Bien que cette question puisse être ancienne, elle est toujours très applicable aux nouveaux projets, même maintenant, j'ai donc passé beaucoup de temps à lire les réponses présentées ici et ailleurs.
Comme @Marco a souligné les différents cas dans lesquels un 404 peut se produire, j'ai vérifié la solution que j'ai compilée ensemble par rapport à cette liste. En plus de sa liste d'exigences, j'en ai également ajouté une de plus.
Cette solution est double:
La première partie vient de @Guillaume à https://stackoverflow.com/a/27354140/2310818 . Leur solution prend en charge tous les 404 causés par un itinéraire non valide, un contrôleur non valide et une action non valide.
L'idée est de créer un WebForm, puis de le faire appeler l'action NotFound de votre contrôleur d'erreurs MVC. Il fait tout cela sans redirection, vous ne verrez donc pas un seul 302 dans Fiddler. L'URL d'origine est également conservée, ce qui rend cette solution fantastique!
La deuxième partie vient de @ Germán à https://stackoverflow.com/a/5536676/2310818 . Leur solution prend en charge tout 404 retourné par vos actions sous la forme de HttpNotFoundResult () ou lance une nouvelle HttpException ()!
L'idée est d'avoir un filtre qui regarde la réponse ainsi que l'exception levée par vos contrôleurs MVC et d'appeler l'action appropriée dans votre contrôleur d'erreurs. Encore une fois, cette solution fonctionne sans redirection et l'URL d'origine est préservée!
Comme vous pouvez le voir, ces deux solutions offrent ensemble un mécanisme de gestion des erreurs très robuste et elles répondent à toutes les exigences répertoriées par @Marco ainsi qu'à mes exigences. Si vous souhaitez voir un échantillon de travail ou une démonstration de cette solution, veuillez laisser dans les commentaires et je serais heureux de le mettre ensemble.
la source
J'ai parcouru tous les articles, mais rien ne fonctionne pour moi: mon utilisateur requis saisit quoi que ce soit dans votre page d'URL 404 personnalisée.J'ai pensé que c'était très simple.Mais vous devez comprendre la gestion de 404 correctement:
J'ai trouvé cet article très utile. Doit être lu immédiatement. Page d'erreur personnalisée-Ben Foster
la source