Asp.net-Mvc-2

ASP.NET MVC2 + Ninject + NLog(+ 共享主機?)= NullReferenceException

  • March 13, 2017

我有一個基於Tekpub Starter Site的 MVC2 應用程序,因此它使用 Ninject 進行依賴注入,使用 NLog 進行日誌記錄,並在不同的地方使用了一堆其他庫。據我所知,正是這些導致了我的問題。

使用 ASP.NET 開發伺服器 (Cassini) 在我的 PC 上一切正常,但是當我部署到伺服器時(這是一個便宜的共享託管交易),我得到一個 NullReferenceException,它似乎與 Ninject 實例化記錄器有關。

這是我的 Global.asax.cs 的相關部分

protected override void OnApplicationStarted() {
   Logger.Info("App is starting"); // <-- I think this is what's causing the problem

   RegisterRoutes(RouteTable.Routes);
   //MvcContrib.Routing.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
   RegisterAllControllersIn(Assembly.GetExecutingAssembly());
   SetEngines();
}

protected override IKernel CreateKernel() {
   return Container;
}

internal class SiteModule : NinjectModule {
   public override void Load() {
       Bind<ILogger>().To<NLogLogger>();
       // and a couple of others...
   }
}

protected void Application_End() {
   Logger.Info("App is shutting down");
}

protected void Application_Error() {
   Exception lastException = Server.GetLastError();
   Logger.Fatal(lastException);
}

public ILogger Logger {
   get {
       return Container.Get<ILogger>();
       }
   }
   static IKernel _container;
   public static IKernel Container {
       get {
           if (_container == null) {
               _container = new StandardKernel(new SiteModule());
           }
           return _container;
       }
   }

nlog.config

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >

   <targets>
       <!--Useful for debugging-->
       <target name="console" xsi:type="ColoredConsole"
        layout="${date:format=HH\:mm\:ss}|${level}|${stacktrace}|${message}" />

       <target name="file" xsi:type="File" fileName="${basedir}/App_Data/Site.log"
        layout="${date}: ${message}" />

       <target name="eventlog" xsi:type="EventLog" source="My App" log="Application"
       layout="${date}: ${message} ${stacktrace}" />

   </targets>

   <rules>
       <logger name="*" minlevel="Info" writeTo="file" />
       <!-- <logger name="*" minlevel="Fatal" writeTo="eventlog" /> -->
   </rules>
</nlog>

NLogLogger 類:

public class NLogLogger:ILogger {

   private Logger _logger;

   public NLogLogger() {
       _logger = LogManager.GetCurrentClassLogger();
   }

   public void Info(string message) {
       _logger.Info(message);
   }

   // similar for Warn, Debug, etc

堆棧跟踪:

[NullReferenceException: Object reference not set to an instance of an object.]
  NLog.LogManager.GetCurrentClassLogger() +84
  DynamicInjector8cdfc2eb02f8497596a4704e379a4bb4(Object[] ) +40
  Ninject.Activation.Providers.StandardProvider.Create(IContext context) +319
  Ninject.Activation.Context.Resolve() +182
  Ninject.KernelBase.<Resolve>b__4(IContext context) +8
  System.Linq.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x) +32
  System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
  System.Linq.<CastIterator>d__b1`1.MoveNext() +92
  System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +4187840
  Ninject.ResolutionExtensions.Get(IResolutionRoot root, IParameter[] parameters) +149
  Web.Application.get_Logger() in C:\mvcstarter\Web\Global.asax.cs:159
  Web.Application.OnApplicationStarted() in C:\mvcstarter\Web\Global.asax.cs:80
  Ninject.Web.Mvc.NinjectHttpApplication.Application_Start() +535

[HttpException (0x80004005): Object reference not set to an instance of an object.]
  System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +9024793
  System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +131
  System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +194
  System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +339
  System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +253

[HttpException (0x80004005): Object reference not set to an instance of an object.]
  System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +8946484
  System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +97
  System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +256

如果我註釋掉登錄OnApplicationStarted,我會得到一個不同的異常。我不確定它為什麼會發生,因為不應該發生任何日誌記錄,所以我不確定它為什麼要嘗試實例化記錄器。

[NullReferenceException: Object reference not set to an instance of an object.]
  NLog.LogManager.GetCurrentClassLogger() +84
  DynamicInjector5ca7d21cf56b4732957e22cb1bfd8bdd(Object[] ) +40
  Ninject.Activation.Providers.StandardProvider.Create(IContext context) +319
  Ninject.Activation.Context.Resolve() +182
  Ninject.KernelBase.<Resolve>b__4(IContext context) +8
  System.Linq.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x) +32
  System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
  System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +4187840
  Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) +347
  Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) +138
  Ninject.Activation.Providers.<>c__DisplayClass2.<Create>b__1(ITarget target) +17
  System.Linq.WhereSelectArrayIterator`2.MoveNext() +85
  System.Linq.Buffer`1..ctor(IEnumerable`1 source) +325
  System.Linq.Enumerable.ToArray(IEnumerable`1 source) +78
  Ninject.Activation.Providers.StandardProvider.Create(IContext context) +306
  Ninject.Activation.Context.Resolve() +182
  Ninject.KernelBase.<Resolve>b__4(IContext context) +8
  System.Linq.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x) +32
  System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
  System.Linq.<CastIterator>d__b1`1.MoveNext() +92
  System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +4187840
  Ninject.ResolutionExtensions.TryGet(IResolutionRoot root, String name, IParameter[] parameters) +261
  Ninject.Web.Mvc.NinjectControllerFactory.CreateController(RequestContext requestContext, String controllerName) +108
  System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +124
  System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +50
  System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +48
  System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
  System.Web.Mvc.<>c__DisplayClass7.<BeginProcessRequest>b__6() +29
  System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Func`1 func) +38
  System.Web.Mvc.ServerExecuteHttpHandlerAsyncWrapper.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +97
  System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +1508
  System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +77
  System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +28
  System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +22
  System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +372
  System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper htmlHelper, String actionName, String controllerName) +35
  ASP.views_home_index_aspx.__RenderContent2(HtmlTextWriter __w, Control parameterContainer) in c:\HostingSpaces\<snip>\wwwroot\Views\Home\Index.aspx:8
  System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
  System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
  System.Web.UI.Control.Render(HtmlTextWriter writer) +10
  System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
  System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
  System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
  ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\HostingSpaces\<snip>\wwwroot\Views\Shared\Site.Master:48
  System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
  System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
  System.Web.UI.Control.Render(HtmlTextWriter writer) +10
  System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
  System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
  System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
  System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
  System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
  System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +55
  System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
  System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
  System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
  System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3060

我能讓網站正常工作的唯一方法是完全偽造記錄器,我對此一點也不滿意。這是我第一次玩 ASP.NET 共享主機,所以我有點不知所措。有人有什麼有用的建議嗎?

您可以避免使用LogManager.GetCurrentClassLogger()並讓 Ninject 為您解析目前的類名:

將 NLogLogger 類的建構子更改為:

public NLogLogger(string currentClassName) 
{
 _logger = LogManager.GetLogger(currentClassName);
}

並更改 ninject 綁定以解析目前類名:

Bind<ILogger>().To<NLogLogger>()
 .WithConstructorArgument("currentClassName", x => x.Request.ParentContext.Request.Service.FullName);

額外的好處:您的日誌文件現在還包括發出日誌指令的類名。

我知道我的答案對聚會來說有點晚了,但我今天自己也在為此苦苦掙扎,在任何地方都找不到答案。也許這對其他人有幫助。

引用自:https://stackoverflow.com/questions/3438162