Buscar..


Un filtro de acción de registro.

 public class LogActionFilter : ActionFilterAttribute
 {
      public override void OnActionExecuting(ActionExecutingContext filterContext)
      {
           Log("OnActionExecuting", filterContext.RouteData);       
      }

      public override void OnActionExecuted(ActionExecutedContext filterContext)
      {
           Log("OnActionExecuted", filterContext.RouteData);       
      }

      public override void OnResultExecuting(ResultExecutingContext filterContext)
      {
           Log("OnResultExecuting", filterContext.RouteData);       
      }

      public override void OnResultExecuted(ResultExecutedContext filterContext)
      {
           Log("OnResultExecuted", filterContext.RouteData);       
      }


      private void Log(string methodName, RouteData routeData)
      {
           var controllerName = routeData.Values["controller"];
           var actionName = routeData.Values["action"];
           var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName);
           Debug.WriteLine(message, "Action Filter Log");
      }
 }

Filtro de acción de Control de sesión - solicitud de página y ajax

Por lo general, los procesos de autenticación y autorización se realizan mediante cookies y token compatibles en .net MVC. Pero si decide hacerlo usted mismo con Session , puede usar la lógica siguiente para las solicitudes de página y las solicitudes de ajax.

public class SessionControl : ActionFilterAttribute
{
    public override void OnActionExecuting ( ActionExecutingContext filterContext )
    {
        var session = filterContext.HttpContext.Session;

        /// user is logged in (the "loggedIn" should be set in Login action upon a successful login request)
        if ( session["loggedIn"] != null && (bool)session["loggedIn"] )
            return;

        /// if the request is ajax then we return a json object
        if ( filterContext.HttpContext.Request.IsAjaxRequest() )
        {
            filterContext.Result = new JsonResult
            {
                Data = "UnauthorizedAccess",
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
        /// otherwise we redirect the user to the login page
        else
        {
            var redirectTarget = new RouteValueDictionary { { "Controller", "Login" }, { "Action", "Index" } };
            filterContext.Result = new RedirectToRouteResult(redirectTarget);
        }
    }

    public override void OnResultExecuting ( ResultExecutingContext filterContext )
    {
        base.OnResultExecuting(filterContext);
        
        /// we set a field 'IsAjaxRequest' in ViewBag according to the actual request type
        filterContext.Controller.ViewBag.IsAjaxRequest = filterContext.HttpContext.Request.IsAjaxRequest();
    }
}

Ubicaciones de uso del filtro de acción (global, controlador, acción)

Puede colocar filtros de acción en tres niveles posibles:

  1. Global
  2. Controlador
  3. Acción

Colocar un filtro global significa que se ejecutará en las solicitudes a cualquier ruta. La colocación de uno en un controlador hace que se ejecute en las solicitudes de cualquier acción en ese controlador. Colocar uno en una acción significa que se ejecuta con la acción.

Si tenemos este simple filtro de acción:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class CustomActionFilterAttribute : FilterAttribute, IActionFilter
{
    private readonly string _location;

    public CustomActionFilterAttribute(string location)
    {
        _location = location;
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Trace.TraceInformation("OnActionExecuting: " + _location);
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Trace.TraceInformation("OnActionExecuted: " + _location);
    }
}

Podemos agregarlo a nivel global agregándolo a la colección de filtro global. Con la configuración típica del proyecto MVC de ASP.NET, esto se hace en App_Start / FilterConfig.cs.

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

También podemos agregarlo en el controlador y en el nivel de acción, como en un controlador:

[CustomActionFilter("HomeController")]
public class HomeController : Controller
{
    [CustomActionFilter("Index")]
    public ActionResult Index()
    {
        return View();
    }
}

Si ejecutamos la aplicación y miramos la ventana de resultados, veremos los siguientes mensajes:

iisexpress.exe Information: 0 : OnActionExecuting: Global
iisexpress.exe Information: 0 : OnActionExecuting: HomeController
iisexpress.exe Information: 0 : OnActionExecuting: Index
iisexpress.exe Information: 0 : OnActionExecuted: Index
iisexpress.exe Information: 0 : OnActionExecuted: HomeController
iisexpress.exe Information: 0 : OnActionExecuted: Global

Como puede ver, cuando llega la solicitud, los filtros se ejecutan:

  1. Global
  2. Controlador
  3. Acción

Excelentes ejemplos de filtros colocados a nivel global incluyen:

  1. Filtros de autentificación
  2. Filtros de autorizacion
  3. Filtros de registro

Atributo de manejador de excepciones

Este atributo maneja todas las excepciones no manejadas en el código, (esto es principalmente para solicitudes Ajax - que tratan con JSON - pero pueden extenderse)

public class ExceptionHandlerAttribute : HandleErrorAttribute
{
    /// <summary>
    ///   Overriden method to handle exception
    /// </summary>
    /// <param name="filterContext"> </param>
    public override void OnException(ExceptionContext filterContext)
    {
        // If exeption is handled - return ( don't do anything)
        if (filterContext.ExceptionHandled)
            return;

        // Set the ExceptionHandled to true ( as you are handling it here)
        filterContext.ExceptionHandled = true;

        //TODO: You can Log exception to database or Log File

        //Set your result structure 
        filterContext.Result = new JsonResult
        {
            Data = new { Success = false, Message = filterContext .Exception.Message, data = new {} },
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };

    }
}

Digamos que siempre tienes que enviar una respuesta JSON similar a esto:

{ 

    Success: true,  // False when Error
    
    data: {},
    
    Message:"Success" // Error Message when Error

}

Así que en lugar de manejar excepciones en las acciones del controlador, como esto:

public ActionResult PerformMyAction()
{
    try
    {
        var myData = new { myValue = 1};
        
        throw new Exception("Handled", new Exception("This is an Handled Exception"));
        
        return Json(new {Success = true, data = myData, Message = ""});
    
    }
    catch(Exception ex)
    {
        return Json(new {Success = false, data = null, Message = ex.Message});
    }
}

Puedes hacerlo:

[ExceptionHandler]
public ActionResult PerformMyAction()
{
        var myData = new { myValue = 1};
        
        throw new Exception("Unhandled", new Exception("This is an unhandled Exception"));
        
        return Json(new {Success = true, data = myData, Message = ""});
}

O puede agregar a nivel de controlador

[ExceptionHandler]
public class MyTestController : Controller
{
    
    public ActionResult PerformMyAction()
    {
            var myData = new { myValue = 1};
            
            throw new Exception("Unhandled", new Exception("This is an unhandled Exception"));
            
            return Json(new {Success = true, data = myData, Message = ""});
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow