Подтвердить что ты не робот

Страница пользовательской ошибки ASP.NET MVC 5

Я использую специальный атрибут authorize в приложении ASP.NET MVC 5, например:

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);
        }
    }
}

В разделе system.web моего web.config я упомянул пути ошибок, например:

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

Но я никогда не перенаправляюсь на страницу пользовательских ошибок в /Error/NoPermissions. Вместо этого браузер отображает общую страницу с сообщением об ошибке "HTTP Error 403.0 - Forbidden" .

4b9b3361

Ответ 1

Спасибо всем, но проблема не в коде 403. На самом деле проблема была в том, как я пытался вернуть 403. Я только что изменил свой код, чтобы выбросить HttpException вместо возврата HttpStatusCodeResult, и теперь все работает. Я могу вернуть любой код состояния HTTP, выбрасывая исключение HttpException, а моя конфигурация customErrors улавливает все из них. Может быть, HttpStatusCodeResult не выполняет точного задания, которое я ожидал от него.

Я только что заменил

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

с

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

Что это.

Счастливое кодирование.

Ответ 2

[1]: удалить все "customErrors" и "httpErrors" из Web.config

[2]: Проверить 'App_Start/FilterConfig.cs' выглядит так:

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

[3]: в 'Global.asax' добавьте этот метод:

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]: ​​Добавить 'Controllers/ErrorPageController.cs'

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

[5]: в разделе "Просмотры/Общие/Ошибка .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

Ответ 3

У меня также была эта проблема. Код в вопросе OPs отлично работает, кроме настраиваемого кода ошибки в разделе <system.web> в файле web.config. Чтобы исправить проблему, мне нужно добавить следующий код в <system.webServer>. Обратите внимание, что ‘webserver’ вместо ‘web’.

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

Если кто-то использует следующую среду, вот полное решение:

Среда:

  • Обновление Visual Studio 2013 4
  • Microsoft.NET Framework 4.5.1 с ASP.NET MVC 5
  • Проект: веб-приложение ASP.NET с MVC и аутентификация: индивидуальный шаблон учетной записи пользователя

Пользовательский класс атрибута:

Добавьте следующий класс в пространство имен по умолчанию для веб-сайтов. Причина, объясняемая здесь в принятом ответе Вопрос о переполнении стека: Почему AuthorizeAttribute перенаправляет на страницу входа для проверки подлинности и авторизации?

[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);
        }
    }
} 

Затем добавьте следующий код web.config file

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

В следующей статье объясните подробнее об этом: ASP.NET MVC: Улучшение атрибута авторизации (403 Запрещено)

И httpErrors в разделе web.config в этой статье: Демистификация страниц ASP.NET MVC 5 и журнала ошибок

Затем добавьте папку ErrorController.cs в папку контроллеров

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

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

}

Затем добавьте UnAuthorized.cshtml в папку View/Shared

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

Это покажет страницу с измененной ошибкой вместо страницы с ошибкой, созданной браузером.

Также обратите внимание, что для указанной выше среды не требуется комментировать код внутри метода RegisterGlobalFilters, добавленный шаблоном, как предлагается в одном из ответов.

Обратите внимание, что я просто вырезал и вставлял код из моего рабочего проекта, поэтому я использовал Unauthorized вместо OPs NoPermissions в приведенном выше коде.

Ответ 4

так как я столкнулся с очень похожим вопросом, я хотел пролить больше света на него.

customErrors будет захватывать только фактические исключения для HTTP, созданные в вашем приложении ASP.NET. Однако HttpStatusCodeResult не генерирует исключение. Он просто пишет ответ с соответствующим кодом состояния, что имеет больше смысла в вашем примере.

Если вы работаете в IIS 7.0 или выше, вы должны теперь использовать httpErrors, так как во всех случаях будут отображаться страницы пользовательских ошибок. Это настройка уровня IIS.

Я написал целую запись в блоге об этом, чтобы объяснить различия: http://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging

Ответ 5

Обновление

Вам нужно только сделать это специальное перенаправление для 403 ошибок. Все остальные 500 ошибок должны вступить в силу через настройку defaultRedirect="/Error/Error" в customErrors. Однако вам нужно удалить или прокомментировать регистрацию HandleErrorAttribute в файле App_Start/FilterConfig.cs, чтобы пользовательские ошибки действительно работали. В противном случае этот атрибут перенаправляет все ошибки в файл Error.cshtml в каталоге Views/Shared.

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

Оригинальный ответ

Насколько я знаю, вы не можете использовать customErrors в web.config для обработки 403 ошибок по какой-либо причине. Я чувствую вашу боль, поскольку это похоже на то, что должно быть таким же простым, как и код, который у вас уже есть, но, видимо, 403 ошибки рассматриваются как проблема с веб-сервером.

Вместо этого вы можете просто перенаправить пользователя на нужную страницу "NoPermissions" следующим образом:

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);
        }
    }
}

Запрос будет иметь код состояния 200 вместо 403, но если вы можете жить с этим, это будет непростым решением.

Вот аналогичный вопрос SO для получения дополнительной информации: Возврат пользовательских ошибок.

Кроме того, в этой статье объясняется, как перейти на маршрут IIS: http://kitsula.com/Article/MVC-Custom-Error-Pages