ASP.NET strona błędu MVC 5 Custom

Używam niestandardowego atrybutu authorize w ASP.NET MVC 5 zastosowanie jak poniżej:

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext context)
    {
        if (context.HttpContext.Request.IsAuthenticated)
        {
            context.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);                
        }
        else
        {
            base.HandleUnauthorizedRequest(context);
        }
    }
}

W system.web sekcji mojej strony.config wspomniałem o ścieżkach błędów takich jak:

<system.web>
    <customErrors mode="On" defaultRedirect="/Error/Error">
      <error statusCode="403" redirect="/Error/NoPermissions"/>
    </customErrors>
</system.web>

Ale nigdy nie jestem przekierowany do mojej niestandardowej strony błędu w /Error/NoPermissions. Zamiast tego przeglądarka wyświetla ogólną stronę błędu z napisem "Błąd HTTP 403.0-Forbidden" .

Author: Haider, 2014-05-09

6 answers

[1]: Usuń wszystkie 'customErrors' i 'httpErrors' z Internetu.config

[2]: Sprawdź ' App_Start / FilterConfig.cs ' wygląda tak:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }
}

[3]: in 'Global.asax ' dodaj tę metodę:

public void Application_Error(Object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Server.ClearError();

    var routeData = new RouteData();
    routeData.Values.Add("controller", "ErrorPage");
    routeData.Values.Add("action", "Error");
    routeData.Values.Add("exception", exception);

    if (exception.GetType() == typeof(HttpException))
    {
        routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
    }
    else
    {
        routeData.Values.Add("statusCode", 500);
    }

    Response.TrySkipIisCustomErrors = true;
    IController controller = new ErrorPageController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();
}

[4]: Dodaj ' Controllers / ErrorPageController.cs '

public class ErrorPageController : Controller
{
    public ActionResult Error(int statusCode, Exception exception)
    {
         Response.StatusCode = statusCode;
         ViewBag.StatusCode = statusCode + " Error";
         return View();
    }
}

[5]: in ' Views/Shared / Error.cshtml "

@model System.Web.Mvc.HandleErrorInfo
@{
    ViewBag.Title = (!String.IsNullOrEmpty(ViewBag.StatusCode)) ? ViewBag.StatusCode : "500 Error";
}

<h1 class="error">@(!String.IsNullOrEmpty(ViewBag.StatusCode) ? ViewBag.StatusCode : "500 Error"):</h1>

//@Model.ActionName
//@Model.ControllerName
//@Model.Exception.Message
//@Model.Exception.StackTrace

:D

 44
Author: ubik404,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-08 13:31:16

Dziękuję wszystkim, ale problem nie jest z kodem 403. Właściwie problem polegał na tym, jak próbowałem zwrócić 403. Po prostu zmieniłem mój kod, aby rzucić HttpException zamiast zwracać HttpStatusCodeResult i wszystko działa teraz. Mogę zwrócić dowolny kod statusu HTTP, rzucając wyjątek HttpException, a moja konfiguracja customErrors przechwyci wszystkie z nich. Być może HttpStatusCodeResult nie wykonuje dokładnie tej pracy, jakiej się spodziewałam.

Właśnie wymieniłem

context.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);

Z

throw new HttpException((int)System.Net.HttpStatusCode.Forbidden, "Forbidden");
To wszystko.

Happy kodowanie.

 18
Author: Haider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-09 20:34:36

Ja też miałem ten problem. Kod w pytaniu OP działa doskonale z wyjątkiem niestandardowego kodu błędu w sekcji <system.web> w pliku web.config. Aby rozwiązać ten problem, muszę dodać następujący kod do <system.webServer>. Zauważ, że ‘webserver’ zamiast ‘web’.

<httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="403" />
  <error statusCode="403" responseMode="ExecuteURL" path="/Error/UnAuthorized" />
</httpErrors>

Jeśli ktoś używa następującego środowiska, oto kompletne rozwiązanie:

Środowisko:

  • Visual Studio 2013 Update 4
  • Microsoft. NET Framework 4.5.1 z ASP.NET MVC 5
  • projekt: ASP.NET Web Application with MVC & Authentication: Individual User Account template

Klasa atrybutów niestandardowych:

Dodaj następującą klasę do domyślnej przestrzeni nazw witryny. Powód wyjaśniony tutaj w zaakceptowanej odpowiedzi pytanie o przepełnienie stosu: dlaczego AuthorizeAttribute przekierowuje na stronę logowania w przypadku błędów uwierzytelniania i autoryzacji?

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);

        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
} 

Następnie dodaj następujący kod web.config plik

<system.webServer>
   <httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="403" />
      <error statusCode="403" responseMode="ExecuteURL" path="/Error/UnAuthorized" />
   </httpErrors>
</system.webServer>

Poniższy artykuł wyjaśnia więcej na ten temat: ASP.NET MVC: ulepszenie atrybutu Authorize (403)

I httpErrors w sieci.Config sekcja w tym artykule: Demystifying ASP.NET strony błędów MVC 5 i rejestrowanie błędów

Następnie dodaj Kontroler ErrorController .cs do folderu Controllers

public class ErrorController : Controller
{
    // GET: UnAuthorized
    public ActionResult UnAuthorized()
    {
        return View();
    }

    public ActionResult Error()
    {
        return View();
    }

}

Następnie dodaj nieautoryzowane.cshtml to View/Shared folder

@{
    ViewBag.Title = "Your Request Unauthorized !"; //Customise as required
 }
 <h2>@ViewBag.Title.</h2> 

To pokaże dostosowana strona błędu zamiast strony błędu generowanej przez przeglądarkę.

Zauważ również, że w powyższym środowisku nie jest wymagane komentowanie kodu wewnątrz metody RegisterGlobalFilters dodanej przez szablon, jak sugerowano w jednej z odpowiedzi.

Proszę zauważyć, że po prostu wyciąłem i wklejałem kod z mojego pracującego projektu, dlatego użyłem Unauthorized zamiast NoPermissions W powyższym kodzie.

 15
Author: Dush,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:09

Ponieważ natknąłem się na bardzo podobny problem, chciałem rzucić na niego więcej światła.

CustomErrors przechwyci tylko rzeczywiste wyjątki http rzucone w Twoim ASP.NET podanie. HttpStatusCodeResult nie rzuca jednak wyjątku. Po prostu pisze odpowiedź z kodem stanu Accord, co ma większy sens w twoim przykładzie.

Jeśli używasz usługi IIS 7.0 lub wyższej, powinieneś teraz używać httpErrors, ponieważ będzie to wyświetlać niestandardowe strony błędów we wszystkich przypadkach. To jest IIS ustawienie poziomu.

Napisałem cały wpis na blogu o tym, aby wyjaśnić różnice: http://dusted.codes / demystifying-aspnet-mvc-5-error-pages-and-error-logging

 2
Author: dustinmoris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-06 23:03:00

To wydają się być skomplikowane obejścia. Oto w zasadzie wszystko, co musisz zrobić, aby Twoje niestandardowe strony błędów (CEP) działały:

  1. Dodaj Kontroler błędów w folderze Kontrolery.
  2. wewnątrz kontrolera błędów dodaj adnotację klasy za pomocą [HandleError].
  3. dla każdego błędu, dla którego chcesz wyświetlić CEP, Utwórz metodę ActionResult.
  4. Utwórz widok dla każdego CEP w folderze ~/Views/Shared/Error i dostosuj go w dowolny sposób. (The Folder błędu powinien zostać utworzony podczas tworzenia kontrolera. Jeśli tak się nie stało, najpierw musisz utworzyć folder błędu.)
  5. Otwórz www.plik konfiguracyjny na poziomie głównym *Uwaga: Istnieją dwa (2) web.pliki konfiguracyjne. Jeden w folderze widoki, drugi na poziomie głównym aplikacji.
  6. wewnątrz <system.web>, dodaj <customError mode="On" defaultRedirect="~/Error/Error">
  7. dla każdego kodu błędu, dla którego masz CEP; dodaj <error statusCode="[StatusCode]" redirect="~/Error/[CEP Name]">. Możesz pominąć rozszerzenie pliku.

Kontroler Przykład:

namespace NAMESPACE_Name.Controllers
{
    [HandleError]
    public class ErrorController : Controller
    {
        // GET: Error
        public ActionResult BadRequest()
        {
            return View();
        }

        public ActionResult Error()
        {
            return View();
        }

        public ActionResult Forbidden()
        {
            return View();
        }

        public ActionResult InternalServerError()
        {
            return View();
        }

        public ActionResult NotFound()
        {
            return View();
        }

        public  ActionResult NotImplemented()
        {
            return View();
        }

        public ActionResult ServerBusyOrDown()
        {
            return View();
        }

        public ActionResult ServerUnavailable()
        {
            return View();
        }

        public ActionResult Timeout()
        {
            return View();
        }

        public ActionResult Unauthorized()
        {
            return View();
        }
    }
}

Zobacz Przykład:

@{ 
    Layout = "~/Views/Shared/_FullWidthLayout.cshtml";
    ViewBag.Title = "404 Error";
}
<div class="opensans margin-sides text-center">
    <div class="text-center">
        <h1 class="text-normal">Uh oh! Something went wrong!</h1>
        <div class="img-container text-center">
            <div class="centered">
                <h1 class="bold">404 - Not Found</h1>
            </div>
            <img class="img text-center" src="~/Images/BackgroundImg.png" style="opacity: 0.15;" />
        </div>
        <p class="text-left">
            This is usually the result of a broken link, a web page that has been moved or deleted, or a mistyped URL.
            <ol class="text-left">
                <li>Check the URL you entered in the address bar for typos,</li>
                <li>If the address you entered is correct, the problem is on our end.</li>
                <li>Please check back later as the resource you requested could be getting worked on,</li>
                <li>However, if this continues for the resource you requested, please submit a <a href="mailto:EmailAddress?subject=Website%20Error">trouble ticket</a>.</li>
            </ol>
        </p>
    </div>
</div>

Www.Przykład Konfiguracji:

<customErrors mode="On" defaultRedirect="~/Error/Error">
  <!--The defaultRedirect page will display for any error not listed below.-->
  <error statusCode="400" redirect="~/Error/BadRequest"/>
  <error statusCode="401" redirect="~/Error/Unauthorized"/>
  <error statusCode="403" redirect="~/Error/Forbidden"/>
  <error statusCode="404" redirect="~/Error/NotFound"/>
  <error statusCode="408" redirect="~/Error/Timeout"/>
  <error statusCode="500" redirect="~/Error/InternalServerError"/>
  <error statusCode="501" redirect="~/Error/NotImplemented"/>
  <error statusCode="502" redirect="~/Error/ServerUnavailable"/>
  <error statusCode="503" redirect="~/Error/ServerBusyOrDown"/>
</customErrors>
To jest to! Krok po kroku rozwiązanie problemu, który naprawdę nie powinien być problemem!
 2
Author: NMeneses,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-03 20:24:40

Update

Wystarczy zrobić specjalne przekierowanie dla błędów 403. Wszystkie pozostałe 500 błędów powinno zadziałać poprzez ustawienie defaultRedirect="/Error/Error" w customErrors. Musisz jednak usunąć lub skomentować rejestrację HandleErrorAttribute w App_Start/FilterConfig.plik cs dla niestandardowych błędów, aby rzeczywiście działać. W przeciwnym razie atrybut ten przekieruje wszystkie błędy do błędu.plik cshtml w katalogu Views / Shared.

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        // remove this line below
        //filters.Add(new HandleErrorAttribute());
    }
}

Oryginał ODPOWIEDŹ

Z tego co wiem, nie można używać customErrors w sieci.config do obsługi błędów 403 z jakiegoś powodu. Czuję twój ból, ponieważ wydaje się, że coś, co powinno być tak proste, jak kod, który już masz, ale najwyraźniej błędy 403 są traktowane jako problem serwera www.

Zamiast tego możesz przekierować użytkownika na żądaną stronę "NoPermissions" w następujący sposób:

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext context)
    {
        if (context.HttpContext.Request.IsAuthenticated)
        {
            context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
            {
                action = "NoPermissions",
                controller = "Error",
                area = ""
            }));
        }
        else
        {
            base.HandleUnauthorizedRequest(context);
        }
    }
}

Żądanie będzie miało kod statusu 200 zamiast 403, ale jeśli możesz żyć dzięki temu jest to łatwe obejście.

Oto podobne pytanie, aby uzyskać więcej informacji: zwracanie błędów niestandardowych.

Ponadto w tym artykule wyjaśniono, jak przejść trasę IIS: http://kitsula.com/Article/MVC-Custom-Error-Pages

 0
Author: ryanulit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:52