我正在使用webapi2和Castle Windsor。我试图拦截对ApiController的调用来进行一些日志记录,但我在参数中找不到调用的方法,url,参数等。返回的方法名称是ExecuteAsync。
这是我的拦截器调用(被击中)
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
var methodName = invocation.Method.Name;
invocation.Proceed();
}
}
答案 0 :(得分: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()
等等。)
答案 1 :(得分:0)
虽然使用ASP.NET MVC框架可以从LoginInterceptor获取动作调用者(检查this link),但在ASP.NET Web Api中我还没有找到使用Castle Windsor拦截器实现它的正确方法
另一方面,我找到了一种方法,可以利用Caller Info Attributes
和Castle Windsor LoggingFacility
组件来实现您的目标。
来电者信息属性
这些属性是
你可以这样使用它们(作为可选参数):
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);
}
调用ShowCallerInfo();
方法(不带参数)显示:
Caller Name: Main
Caller FilePath: h:\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1\Class1.cs
Caller Line number: 7
<强> LoggingFacility 强>
Castle Windsor提供LoggingFacility
组件作为Logging的替代方法(使用注入而不是拦截),允许在方法内部进行记录,不仅仅是在拦截器之后和之后(允许使用拦截器)。
只需以这种方式注册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");
…
}
...
}
示例强>
因此,作为示例,您可以混合使用这两种功能来实现以这种方式记录控制器操作:
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
);
}
...
}