Ricerca…


Un filtro di azione di registrazione

 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 azioni di controllo sessione: richiesta di pagina e ajax

Solitamente i processi di autenticazione e autorizzazione vengono eseguiti tramite cookie e token support integrati in .net MVC. Ma se decidi di farlo da solo con Session puoi usare la logica sottostante per entrambe le richieste di pagina e le richieste di 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();
    }
}

Posizioni di utilizzo del filtro delle azioni (globale, controller, azione)

Puoi posizionare i filtri di azione a tre livelli possibili:

  1. Globale
  2. controllore
  3. Azione

Posizionare un filtro a livello globale significa che verrà eseguito su richieste a qualsiasi percorso. L'inserimento di uno su un controller lo rende eseguibile su richieste di qualsiasi azione in quel controller. Mettendo uno su un'azione significa che corre con l'azione.

Se abbiamo questo semplice filtro azione:

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

Possiamo aggiungerlo a livello globale aggiungendolo alla raccolta di filtri globale. Con la tipica configurazione del progetto ASP.NET MVC, ciò avviene in App_Start / FilterConfig.cs.

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

Possiamo anche aggiungerlo al controller e al livello di azione in questo modo in un controller:

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

Se eseguiamo l'applicazione e guardiamo la finestra Output, vedremo i seguenti messaggi:

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

Come puoi vedere, quando arriva la richiesta, i filtri vengono eseguiti:

  1. Globale
  2. controllore
  3. Azione

Esempi eccellenti di filtri posizionati a livello globale includono:

  1. Filtri di autenticazione
  2. Filtri di autorizzazione
  3. Registrazione dei filtri

Attributo gestore di eccezioni

Questo attributo gestisce tutte le eccezioni non gestite nel codice, (questo è principalmente per le richieste Ajax - che riguardano JSON - ma può essere esteso)

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

    }
}

Supponiamo che tu debba sempre inviare una risposta JSON simile a questa:

{ 

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

}

Quindi, invece di gestire le eccezioni nelle azioni del controller, come questo:

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

Puoi farlo:

[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 puoi aggiungere a livello di Controller

[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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow