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");
}
23
demandé sur Community 2011-07-18 16:44:27

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"/>
34
répondu javad amiry 2011-09-08 01:36:59

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.

10
répondu Tridus 2011-07-18 13:02:09

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 .

9
répondu TheCodeKing 2011-09-09 23:28:56

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.

0
répondu Justin 2011-09-14 00:31:39