tag route net mvc for etiquetas cshtml asp asp.net-mvc handleerror

route - Error 401 amigable para el usuario de ASP.NET MVC



select asp-for (4)

En uno de mis proyectos, uso el código de .

Tengo ASP.NET MVC2 y uso la autenticación de Active Directory sin página de inicio de sesión. Tengo una página NoAuth.aspx que usa la página maestra del sitio, integro el diseño de la aplicación web.

Este es el web.config.

<system.web> <authentication mode="Windows" /> <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider"> <providers> <clear /> <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" /> </providers> </roleManager> </system.web>

La nueva clase CustomAutorizeAttribute

using System.Web.Mvc; public class CustomAuthorizeAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { base.HandleUnauthorizedRequest(filterContext); } else { filterContext.Result = new ViewResult { ViewName = "NoAuth"}; } } }

y el controlador

[CustomAuthorize(Roles = "ADRole")] public class HomeController : Controller { public HomeController() { } }

He implementado el manejo de errores en el sitio de ASP.NET MVC de la manera que sugiere esta publicación .

Con 404 errores todo funciona bien. Pero, ¿cómo se muestra correctamente la pantalla fácil de usar para un error 401 ? Por lo general, no lanzan Excepciones que pueden manejarse dentro de Application_Error() sino que la acción devuelve HttpUnauthorizedResult. Una forma posible es agregar el siguiente código al final del método Application_EndRequest()

if (Context.Response.StatusCode == 401) { throw new HttpException(401, "You are not authorised"); // or UserFriendlyErrorRedirect(new HttpException(401, "You are not authorised")), witout exception }

Pero dentro de Application_EndRequest() Context.Session == null, errorController.Execute() falla porque no puede usar TempDataProvider predeterminado.

// Call target Controller and pass the routeData. IController errorController = new ErrorController(); errorController.Execute(new RequestContext( new HttpContextWrapper(Context), routeData)); // Additional information: The SessionStateTempDataProvider requires SessionState to be enabled.

Entonces, ¿puede sugerir algunas prácticas recomendadas sobre cómo ''manejar fácilmente'' 401 en la aplicación MVC de ASP.NET?

Gracias.


Logré resolver esto de una manera muy simple. Quería mostrar una página personalizada para los usuarios registrados ("no tiene permiso bla bla ...") y redirigir a los usuarios no autenticados a la página de inicio de sesión (el comportamiento predeterminado). Así que implementé un AuthorizeAttribute personalizado (por ejemplo, CustomAuthorizeAttribute) con el método HandleUnauthorizedRequest sobrescrito de manera que si el usuario está autenticado, establezco la propiedad Result del argumento filterContext con un ViewResult (en la carpeta Compartida) llamado AccessDenied.aspx

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { base.HandleUnauthorizedRequest(filterContext); } else { filterContext.Result = new ViewResult { ViewName = "AccessDenied" }; } }

Entonces tienes que usar este nuevo atributo en su lugar. Saludos.


Mira el HandleErrorAttribute. Subclase de él o agregue su propia implementación que manejará todos los códigos de estado que le interesen. Puede hacerlo para devolver una vista de error separada para cada tipo de error.

Aquí hay una idea de cómo crear su filtro de excepción de error de identificador. He tirado la mayoría de las cosas para centrarme solo en lo esencial. Absolutamente eche un vistazo a la implementación original para agregar verificaciones de argumentos y otras cosas importantes.

public class HandleManyErrorsAttribute : FilterAttribute, IExceptionFilter { public virtual void OnException(ExceptionContext filterContext) { if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) return; Exception exception = filterContext.Exception; string viewName = string.Empty; object viewModel = null; int httpCode = new HttpException(null, exception).GetHttpCode(); if (httpCode == 500) { viewName = "Error500View"; viewModel = new Error500Model(); } else if (httpCode == 404) { viewName = "Error404View"; viewModel = new Error404Model(); } else if (httpCode == 401) { viewName = "Error401View"; viewModel = new Error401Model(); } string controllerName = (string)filterContext.RouteData.Values["controller"]; string actionName = (string)filterContext.RouteData.Values["action"]; filterContext.Result = new ViewResult { ViewName = viewName, MasterName = Master, ViewData = viewModel, TempData = filterContext.Controller.TempData }; filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.StatusCode = httpCode; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; } }

Luego, "decoras" tus acciones de controlador con este atributo:

[HandleManyErrors] public ActionResult DoSomethingBuggy () { // ... }


Si está utilizando ASP.NET MVC, es más que probable que use IIS, ¿por qué no configura IIS para usar su página de error 401 personalizada para esa aplicación web / directorio virtual?