I have a base controller class with ILog log
field, which is set at constructor from custom logger service, passed via dependency injection.
I'd like to access something like request context in controller constructor to get arbitrary HTTP header or HttpContext.Items
or something like that to use it when creating my log
.
I tried using IHttpContextAccessor
. It gives me DefaultHttpContext
which does not contain Items
added by middleware.
The only thing that i can imagine is to make log
property of controller public
and write an IActionFilter
which sets this property. Because action filters have access to both context and controller instance.
Not having request context in controller constructor looks weird to me, because request information can be useful to avoid boilerplate code in actions. Controllers are created per request anyway, so there's no harm to use some request data in constructor.
For request level logging use an ActionFilter
attrbute and inject an ILogger
to that. I'm not sure but I think in MVC 5+ the dependency injection is supported in action filter attributes. If not, instead of registering in GlobalFilters
, you can implement an IFilterProvider
for attaching and instantiating the attribute to the requests you'd like to.
On the other hand, if you need any kind of business level logging (so for example inside an action body), use the injected ILogger
in the controller, but then you should not call any logging logic until the process is inside an action. At that point you'll already have a built-up request context.