Comment afficher les pages d'erreur personnalisées dans Asp.Net Mvc 3?
je veux que toutes les erreurs 401 soient redirigées vers une page d'erreur personnalisée. J'ai d'abord configuration de l'entrée suivante dans mon web.config.
<customErrors defaultRedirect="ErrorPage.aspx" mode="On">
<error statusCode="401" redirect="~/Views/Shared/AccessDenied.aspx" />
</customErrors>
lorsque J'utilise IIS Express, je reçois la page d'erreur stock IIS Express 401.
dans le cas où je n'utilise pas IIS Express, une page vierge est retournée. En utilisant L'onglet Réseau de Google Chrome pour inspecter la réponse, je vois que pendant que la page est vide un statut 401 est retourné dans les en-têtes
ce que j'ai essayé jusqu'à présent est d'utiliser les suggestions de cette réponse ainsi depuis que j'utilise IIS Express mais en vain. J'ai essayé d'utiliser une combinaison <custom errors>
et <httpErrors>
sans succès - l'erreur standard ou la page vierge est toujours affichée.
la section httpErrors
ressemble à ceci en ce moment basé sur le lien du ci-dessus ainsi question (I aussi trouvé un autre très réponse prometteuse cependant pas de chance-réponse vide)
<system.webServer>
<httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" >
<remove statusCode="401" />
<error statusCode="401" path="/Views/Shared/AccessDenied.htm" />
</httpErrors>
<!--
<httpErrors errorMode="Custom"
existingResponse="PassThrough"
defaultResponseMode="ExecuteURL">
<remove statusCode="401" />
<error statusCode="401" path="~/Views/Shared/AccessDenied.htm"
responseMode="File" />
</httpErrors>
-->
</system.webServer>
j'ai même modifié le fichier applicationhost.config
et modifié <httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath">
en <httpErrors lockAttributes="allowAbsolutePathsWhenDelegated">
basé sur des informations de iis.net . Au cours de mes efforts, j'ai également réussi à tomber sur cette erreur comme décrit dans une autre question .
Comment puis-je afficher personnalisé pages d'erreur dans Asp.Net Mvc 3?
informations supplémentaires
les actions suivantes du contrôleur ont été décorées de l'attribut Authorise
pour un utilisateur spécifique.
[HttpGet]
[Authorize(Users = "domainuserXYZ")]
public ActionResult Edit()
{
return GetSettings();
}
[HttpPost]
[Authorize(Users = "domainuserXYZ")]
public ActionResult Edit(ConfigurationModel model, IList<Shift> shifts)
{
var temp = model;
model.ConfiguredShifts = shifts;
EsgConsole config = new EsgConsole();
config.UpdateConfiguration(model.ToDictionary());
return RedirectToAction("Index");
}
4 réponses
j'utilise ces étapes:
// in Global.asax.cs:
protected void Application_Error(object sender, EventArgs e) {
var ex = Server.GetLastError().GetBaseException();
Server.ClearError();
var routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Index");
if (ex.GetType() == typeof(HttpException)) {
var httpException = (HttpException)ex;
var code = httpException.GetHttpCode();
routeData.Values.Add("status", code);
} else {
routeData.Values.Add("status", 500);
}
routeData.Values.Add("error", ex);
IController errorController = new Kavand.Web.Controllers.ErrorController();
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
protected void Application_EndRequest(object sender, EventArgs e) {
if (Context.Response.StatusCode == 401) { // this is important, because the 401 is not an error by default!!!
throw new HttpException(401, "You are not authorised");
}
}
et:
// in Error Controller:
public class ErrorController : Controller {
public ActionResult Index(int status, Exception error) {
Response.StatusCode = status;
return View(status);
}
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
}
}
et la vue d'index dans le dossier D'erreur:
@* in ~/Views/Error/Index.cshtml: *@
@model Int32
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Kavand | Error</title>
</head>
<body>
<div>
There was an error with your request. The error is:<br />
<p style=" color: Red;">
@switch (Model) {
case 401: {
<span>Your message goes here...</span>
}
break;
case 403: {
<span>Your message goes here...</span>
}
break;
case 404: {
<span>Your message goes here...</span>
}
break;
case 500: {
<span>Your message goes here...</span>
}
break;
//and more cases for more error-codes...
default: {
<span>Unknown error!!!</span>
}
break;
}
</p>
</div>
</body>
</html>
et-la dernière étape:
<!-- in web.config: -->
<customErrors mode="Off"/>
Je n'ai jamais été en mesure d'obtenir CustomErrors dans un web.config et MVC pour jouer ensemble, alors j'ai abandonné. - Je faire à la place.
dans global.asax:
protected void Application_Error()
{
var exception = Server.GetLastError();
var httpException = exception as HttpException;
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "Errors";
routeData.Values["action"] = "General";
routeData.Values["exception"] = exception;
Response.StatusCode = 500;
if (httpException != null)
{
Response.StatusCode = httpException.GetHttpCode();
switch (Response.StatusCode)
{
case 403:
routeData.Values["action"] = "Http403";
break;
case 404:
routeData.Values["action"] = "Http404";
break;
}
}
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
IController errorsController = new GNB.LG.StrategicPlanning.Website.Controllers.ErrorsController();
HttpContextWrapper wrapper = new HttpContextWrapper(Context);
var rc = new RequestContext(wrapper, routeData);
errorsController.Execute(rc);
}
Dans ErrorsController:
public class ErrorsController
{
public ActionResult General(Exception exception)
{
// log the error here
return View(exception);
}
public ActionResult Http404()
{
return View("404");
}
public ActionResult Http403()
{
return View("403");
}
}
dans web.config:
<customErrors mode="Off" />
cela a fonctionné pour moi, Peu importe où ou comment l'erreur est créée. La 401 n'y est pas en ce moment, mais vous pouvez l'ajouter facilement.
peut-être que je manque quelque chose, mais MVC a un global par défaut ErrorHandlerAttribute
qui utilise des erreurs personnalisées. Ceci est très bien expliqué ici .
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
vous N'avez qu'à activer custom errors
dans la configuration, puis configurer les redirections d'erreurs personnalisées, de préférence vers un fichier HTML
statique (en cas d'erreurs avec l'application).
<customErrors mode="On" defaultRedirect="errors.htm">
<error statusCode="404" redirect="errors404.htm"/>
</customErrors>
Si vous préférez puisse également personnalisé Controller
pour afficher les erreurs. Dans l'exemple suivant , je viens d'utiliser le routage par défaut vers un Controller
nommé Error
, avec une action appelée Index
, et le paramètre de chaîne de caractères nommé id
(pour recevoir l'errorcode). Vous pouvez bien sûr utiliser n'importe quel routage que vous désirez. Votre exemple ne fonctionne pas parce que vous essayez de vous connecter directement dans le répertoire Views
sans passer par un Controller
. MVC .net ne sert pas directement les requêtes dans le dossier Views
.
<customErrors mode="On" defaultRedirect="/error/index/500">
<error statusCode="404" redirect="/error/index/404"/>
</customErrors>
le ErrorHandlerAttribute peut aussi être utilisé intensivement avec Controllers/Actions
pour rediriger les erreurs à Views
lié au Controller
. Par exemple, pour afficher le View
nommé MyArgumentError
quand une exception de type ArgumentException
se produit, vous pouvez utiliser:
[ControllerAction,ExceptionHandler("MyArgumentError",typeof(ArgumentException))]
public void Index()
{
// some code that could throw ArgumentExcepton
}
bien sûr, une autre option est de mettre à jour le stock Error
page dans Shared
.
regarder la première partie de votre web.config ici, vous pointez vers un .aspx page directement. Lorsque j'ai configuré mes pages d'erreur, j'ai pointé directement vers un contrôleur et une action. Par exemple:
<customErrors mode="On" defaultRedirect="~/Error/UhOh">
<error statusCode="404" redirect="~/Error/NotFound" />
<error statusCode="403" redirect="~/Error/AccessDenied" />
</customErrors>
et j'avais un contrôleur par erreur avec toutes les mesures requises. Je ne pense pas que MVC joue bien avec les appels directs à .les pages aspx.