2014-12-14 3 views
2

Я использую webapi2 и замок Виндзор. Я пытаюсь перехватить вызовы в ApiController, чтобы сделать некоторые протоколирования, но я не могу найти в параметре метод, называемый url, параметры и т. Д. Возвращаемое имя метода - ExecuteAsync.Перехват вызовов webpi2 с Виндзорским замком

Это мой перехватчик вызов (который попал)

public class LoggingInterceptor : IInterceptor 
    { 
     public void Intercept(IInvocation invocation) 
     { 
      var methodName = invocation.Method.Name; 
      invocation.Proceed(); 
     } 
    } 
+0

Вы имеете в виду 'призывание .Arguments'? – PatrickSteele

ответ

2
if (invocation.Method.Name == "ExecuteAsync") 
{ 
    var ctx = (HttpControllerContext) invocation.Arguments[0]; 
    Console.WriteLine("Controller name: {0}", ctx.ControllerDescriptor.ControllerName); 
    Console.WriteLine("Request Uri: {0}", ctx.Request.RequestUri); 
} 
invocation.Proceed(); 

перехватывать вызов ExecuteAsync, вы можете получить доступ к HttpControllerContext, но не HttpActionContext, который содержит сведения о действительном действии метода контроллера. (Насколько я могу судить, это доступно только для ActionFilter).

Поэтому информация о запросе ограничена: например, десериализованные параметры недоступны с использованием этой техники.

Если вы хотите, вы можете сделать свои методы действий с контроллером virtual, после чего они также будут перехвачены, и вы сможете получить доступ к действительным параметрам действия через invocation.arguments. Тем не менее, в вашем перехватчик вам нужно будет каким-то образом дифференцировать методы действий, которые вы хотите войти, от других методов, которые вызываются на контроллере (т.е. Intialize(), Dispose(), ExecuteAsync(), Ok() и т.д.)

0

При использовании рамки ASP.NET MVC можно получить вызывающий действие от LoginInterceptor (проверка this link), в ASP.NET Web Api I убежище Не нашел подходящего пути для его достижения, используя перехватчики с замком Виндзор.

С другой стороны, я нашел способ добиться того, что вы пытаетесь сделать, воспользовавшись Caller Info Attributes и компонентом Castle Windsor LoggingFacility.

Caller Info Атрибуты

Эти атрибуты

  • [CallerMemberName] - Устанавливает информацию об имени члена вызывающего абонента.
  • [CallerFilePath] - Устанавливает информацию об исходном коде вызывающего абонента .
  • [CallerLineNumber] - Устанавливает информацию о номере линии звонящего.

И вы можете использовать их таким образом (как необязательные параметры):

public static void ShowCallerInfo([CallerMemberName] 
     string callerName = null, [CallerFilePath] string 
     callerFilePath = null, [CallerLineNumber] int callerLine=-1) 
{ 
    Console.WriteLine("Caller Name: {0}", callerName); 
    Console.WriteLine("Caller FilePath: {0}", callerFilePath); 
    Console.WriteLine("Caller Line number: {0}", callerLine); 
} 

Calling ShowCallerInfo(); метод (без параметров) отображает:

Caller Name: Main 
Caller FilePath: h:\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1\Class1.cs 
Caller Line number: 7 

LoggingFacility

замок Windsor предоставляет компонент LoggingFacility как alt (с использованием инъекции вместо перехвата), что позволяет вести журнал внутри ваших методов не только после и до (разрешенных с помощью перехватчиков).

Просто регистрации ваш Logger так:

container.AddFacility<LoggingFacility>(f => f.UseNLog().WithConfig("NLog.config")); 

автоматически впрыскивает объект ILogger, который может использовать в своем коде.

public class MyController : ApiController 
{ 
    public ILogger Logger { get; set; } 

    [HttpGet] 
    public IHttpActionResult Get() 
    { 
     Logger.Info("Log Test"); 
     … 
    } 
    ... 
} 

Проверить это link, и это link для получения дополнительной информации.

Пример

Так, в качестве примера, вы можете смешать обе возможности для достижения Logging в действиях контроллера таким образом:

public class MyController : ApiController 
{ 
    // Make Logger optional 
    private ILogger logger = NullLogger.Instance; 
    public ILogger Logger 
    { 
     get { return logger; } 
     set { logger = value; } 
    } 

    [HttpGet] 
    public IHttpActionResult Get() 
    { 
     loggerError("Error"); 

     ... 

     return Ok(); 
    } 

    .... 

    public void loggerError(string message, 
     [CallerMemberName] string memberName = "", 
     [CallerFilePath] string sourceFilePath = "", 
     [CallerLineNumber] int sourceLineNumber = 0) 
    { 
     Logger.Error(message + 
      " - Caller Name: " + memberName 
      + " - Caller FilePath: " + sourceFilePath 
      + " - Line number: " + sourceLineNumber 
     ); 
    } 
    ... 
} 
+0

Да, я использую уже средство ведения журнала, но я не хочу использовать классы, поэтому я хотел бы поместить его в Interceptor ... Thx в любом случае! – polonskyg

Смежные вопросы