visual tutorial studio pagina net mvc establecer español dotnet asp asp.net-mvc logging asp.net-web-api ninject ninject-interception

asp.net-mvc - tutorial - search mvc



¿Cómo interceptar todas las llamadas de los métodos de acción del controlador ASP.NET WebApi con la intercepción Ninject para el registro? (2)

Para cualquier persona que todavía estuviera al acecho, la razón por la que quería usar Ninject era para poder inyectar un registrador (o cualquier otra cosa) en el interceptor, pero quería interceptar todas las acciones.

La respuesta de Mark es perfecta, pero en lugar de registrarse globalmente

GlobalConfiguration.Configuration.Filters.Add(new TimingActionFilter());

une tu filtro con Ninject usando

Kernal.BindHttpFilter<TimingActionFilter>(FilterScope.Action).

Tendrá que crear un contructor apropiado en la clase TimingActionFilter.

Nuestra empresa tiene la necesidad de registrar ciertas cosas cada vez que se llama a uno de nuestros métodos de acción de nuestros controladores ASP.NET WebApi. Ya que usamos Ninject para el DI en este momento, nos gustaría usarlo también para este propósito. Esto es lo que he intentado hasta ahora.

Tengo Ninject, Ninject.Extensions.Interception y Ninject.Extensions.Interception.DynamicProxy instalado a través de NuGet y tengo el siguiente módulo

public class InterceptAllModule : InterceptionModule { public override void Load() { Kernel.Intercept(p => p.Request.Service.Name.EndsWith("Controller")).With(new TimingInterceptor()); } }

Donde TimingInterceptor es

public class TimingInterceptor : SimpleInterceptor { readonly Stopwatch _stopwatch = new Stopwatch(); protected override void BeforeInvoke(IInvocation invocation) { _stopwatch.Start(); } protected override void AfterInvoke(IInvocation invocation) { _stopwatch.Stop(); string message = string.Format("[Execution of {0} took {1}.]",invocation.Request.Method,_stopwatch.Elapsed); Log.Info(message + "/n"); _stopwatch.Reset(); } }

Ahora, cuando intento conectar el módulo con kernel ninject y ejecutar mi sitio

var kernel = new StandardKernel(new InterceptAllModule());

Sin embargo, siempre que hay una llamada que llega a uno de los métodos de acción, se emite un error que dice

Cannot instantiate proxy of class: MyApiController.

¿Podría alguien con experiencia señalar lo que estoy haciendo mal por favor? Gracias.


Actualizar

Por lo tanto, al utilizar el Código y el excelente punto de Remo sobre la necesidad de que los métodos de acción sean virtuales y colocar un constructor predeterminado vacío (solo para aplacar el proxy dinámico, mantener el otro constructor todavía ), tengo el filtro de acción y el enfoque de intercepción funcionando.

Yo diría que tal como está, su código interceptará métodos potencialmente no deseados en el ApiController, por lo que probablemente también necesitará poner un código para filtrarlos, por ejemplo, ExecuteAsync y Disose.

Mi único otro punto es el rendimiento. Enorme descargo de responsabilidad, estas son solo pruebas muy básicas (usando el enfoque del filtro de acción cada vez que se registran las estadísticas), lo invito a hacer su propio (!) ... pero utilizando el interceptor DynamicProxy obtuve un tiempo de alrededor de 4 milisegundos por obtener solicitud

[Execution of Get took 00:00:00.0046615.] [Execution of Get took 00:00:00.0041988.] [Execution of Get took 00:00:00.0039383.]

Comentando el código de Intercepción y usando un filtro de Acción, estaba obteniendo un rendimiento de milisegundos:

[Execution of Get took 00:00:00.0001146.] [Execution of Get took 00:00:00.0001116.] [Execution of Get took 00:00:00.0001364.]

Depende de usted si esto es realmente un problema o una preocupación, pero pensé que lo señalaría.

Respuesta anterior

¿Has eliminado utilizando ActionFilters? Este es el punto de extensión natural para AOP en una acción MVC.

Si estuviera interesado en métodos distintos a la acción real en el controlador, entonces lo entendería, pero pensé que de todos modos publicaría una sugerencia.

Inspirado por ¿Son ActionFilterAttributes reutilizados en hilos? ¿Cómo funciona? y mida el tiempo invocando las acciones del controlador MVC de ASP.NET .

Actualizado para mostrar la exclusión del temporizador cuando el método está etiquetado. Inspiración del marco central de WebApi, específicamente AllowAnonymousAttribute y AuthorizeAttribute

Registre esto globalmente para que todas las acciones sean monitoreadas por esto:

GlobalConfiguration.Configuration.Filters.Add(new TimingActionFilter());

Entonces:

public class TimingActionFilter : ActionFilterAttribute { private const string Key = "__action_duration__"; public override void OnActionExecuting(HttpActionContext actionContext) { if (SkipLogging(actionContext)) { return; } var stopWatch = new Stopwatch(); actionContext.Request.Properties[Key] = stopWatch; stopWatch.Start(); } public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { if (!actionExecutedContext.Request.Properties.ContainsKey(Key)) { return; } var stopWatch = actionExecutedContext.Request.Properties[Key] as Stopwatch; if(stopWatch != null) { stopWatch.Stop(); var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName; Debug.Print(string.Format("[Execution of {0} took {1}.]", actionName, stopWatch.Elapsed)); } } private static bool SkipLogging(HttpActionContext actionContext) { return actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>().Any() || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<NoLogAttribute>().Any(); } }

Y

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)] public class NoLogAttribute : Attribute { }

Ahora puedes excluir el filtro global usando:

public class ExampleController : ApiController { // GET api/example [NoLog] public Example Get() { // } }