Exception thrown when ActionFilter calls another class using ILogger

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 years ago
My plugin class implements a service.  I inject Nop.Services.Logging.ILogger into this service class in my plugin and it works OK when an instance of the class is "called normally" via injection when used as a service.  But now I've added an ActionFilter (in the same plugin) that calls a method in the service class.  When it reaches the _logger.Information() in the service class, an exception is thrown.  It seems as if the httpContext is missing something during the ActionFilter processing:
        
[NullReferenceException: Object reference not set to an instance of an object.]
   Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP() +0
   Microsoft.VisualStudio.WebHost.Request.GetRemoteAddress() +65
   System.Web.HttpRequestWrapper.get_UserHostAddress() +22
   Nop.Core.WebHelper.GetCurrentIpAddress() in \Libraries\Nop.Core\WebHelper.cs:53
   Nop.Services.Logging.DefaultLogger.InsertLog(LogLevel logLevel, String shortMessage, String fullMessage, Customer customer) in \Libraries\Nop.Services\Logging\DefaultLogger.cs:183
   Nop.Services.Logging.LoggingExtensions.FilteredLog(ILogger logger, LogLevel level, String message, Exception exception, Customer customer) in \Libraries\Nop.Services\Logging\LoggingExtensions.cs:39
   Nop.Services.Logging.LoggingExtensions.Information(ILogger logger, String message, Exception exception, Customer customer) in \Libraries\Nop.Services\Logging\LoggingExtensions.cs:15        
   [My Plugin method]
   CallSite.Target(Closure , CallSite , [My Plugin class] , Object ) +259
   [My Namespace].ActionFilters.ActionFilterPreparePaymentInfoModel.OnActionExecuted(ActionExecutedContext filterContext) +630
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +283  
   ...


\Libraries\Nop.Core\WebHelper.cs

        public virtual string GetCurrentIpAddress()
        {
            if (_httpContext != null &&
                _httpContext.Request != null &&
                _httpContext.Request.UserHostAddress != null)
                return _httpContext.Request.UserHostAddress;   <<<<Exception Thrown here
            
            return string.Empty;
        }


Any thoughts / workarounds?
11 years ago
New York wrote:
My plugin class implements a service.  I inject Nop.Services.Logging.ILogger into this service class in my plugin and it works OK when an instance of the class is "called normally" via injection when used as a service.  But now I've added an ActionFilter (in the same plugin) that calls a method in the service class.  When it reaches the _logger.Information() in the service class, an exception is thrown.  It seems as if the httpContext is missing something during the ActionFilter processing:
        
[NullReferenceException: Object reference not set to an instance of an object.]
   Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP() +0
   Microsoft.VisualStudio.WebHost.Request.GetRemoteAddress() +65
   System.Web.HttpRequestWrapper.get_UserHostAddress() +22
   Nop.Core.WebHelper.GetCurrentIpAddress() in \Libraries\Nop.Core\WebHelper.cs:53
   Nop.Services.Logging.DefaultLogger.InsertLog(LogLevel logLevel, String shortMessage, String fullMessage, Customer customer) in \Libraries\Nop.Services\Logging\DefaultLogger.cs:183
   Nop.Services.Logging.LoggingExtensions.FilteredLog(ILogger logger, LogLevel level, String message, Exception exception, Customer customer) in \Libraries\Nop.Services\Logging\LoggingExtensions.cs:39
   Nop.Services.Logging.LoggingExtensions.Information(ILogger logger, String message, Exception exception, Customer customer) in \Libraries\Nop.Services\Logging\LoggingExtensions.cs:15        
   [My Plugin method]
   CallSite.Target(Closure , CallSite , [My Plugin class] , Object ) +259
   [My Namespace].ActionFilters.ActionFilterPreparePaymentInfoModel.OnActionExecuted(ActionExecutedContext filterContext) +630
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +283  
   ...


\Libraries\Nop.Core\WebHelper.cs

        public virtual string GetCurrentIpAddress()
        {
            if (_httpContext != null &&
                _httpContext.Request != null &&
                _httpContext.Request.UserHostAddress != null)
                return _httpContext.Request.UserHostAddress;   <<<<Exception Thrown here
            
            return string.Empty;
        }


Any thoughts / workarounds?


It seems quite impossible for _httpContext.Request.UserHostAddress to throw null reference error, because the code has checked for all possibility of null reference beforehand.

Looking at http://stackoverflow.com/questions/2534261/client-ip-address-in-asp-net-asmx-webservices and http://stackoverflow.com/questions/6076220/why-does-this-work-fine-the-first-time-around-but-not-the-2nd-time-around, it seems like one possible reason for this error to occurred is because of threading issue. And because ActionFilter is NOT instantiated per http request (it is instantiated ONCE per App_Start), and that LoggingExtensions is a static class, threading issue could happen.

What you can try though is to use ILogger directly instead of using LoggingExtensions to do the job. Make sure you initialize your ILogger in your 'ActionExecuted' method using EngineContext.Current.Resolve<> instead of using constructor injection. :)
11 years ago
I guess VS just shows that line because it can't show code in an MS module.  The top of the stack shows the where the real error is thrown

   Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP() +0


I had also tried injecting ILogger into my ActionFilter constructor with same result .   I didn't think about using Resolve - that might work!  I'll try it.   Thanks :)
11 years ago
New York wrote:
I guess VS just shows that line because it can't show code in an MS module.  The top of the stack shows the where the real error is thrown

   Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP() +0


I had also tried injecting ILogger into my ActionFilter constructor with same result .   I didn't think about using Resolve - that might work!  I'll try it.   Thanks :)


Constructor injection won't work in ActionFilter, because ActionFilters are initialized per App_Start. We need to make sure ILogger is initialized differently for every request, so we have to do it in the 'OnActionXXX' method using EngineContext.Current.Resolve to get a fresh copy of ILogger everytime the 'OnActionXXX' method runs. :D
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.