14

Tôi có một ứng dụng MVC2 dựa trên Tekpub Starter Site, vì vậy nó sử dụng Ninject để tiêm phụ thuộc, NLog để ghi nhật ký và một loạt các thư viện khác nơi. Theo như tôi có thể nói mặc dù, đó là những điều đang gây ra vấn đề của tôi.ASP.NET MVC2 + Ninject + NLog (+ shared hosting?) = NullReferenceException

Mọi thứ hoạt động tốt trên PC của tôi bằng máy chủ ASP.NET (Cassini) nhưng khi tôi triển khai đến máy chủ (đó là giao dịch chia sẻ lưu trữ giá rẻ), tôi nhận được NullReferenceException có vẻ liên quan đến Ninject instantiating logger .

Dưới đây là các bit có liên quan của Global.asax.cs của tôi

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; 
     } 
    } 

Các 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> 

Lớp 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 

Stack trace:

[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 

Nếu tôi nhận xét việc đăng nhập OnApplicationStarted, tôi nhận được một ngoại lệ khác. Tôi không chắc chắn lý do tại sao nó xảy ra, bởi vì không nên có bất kỳ đăng nhập xảy ra vì vậy tôi không chắc chắn lý do tại sao nó cố gắng để nhanh chóng các logger.

[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 

Cách duy nhất tôi có thể làm trang web hoàn toàn là giả mạo hoàn toàn trình ghi nhật ký mà tôi hoàn toàn không hài lòng. Đây là lần đầu tiên tôi chơi với ASP.NET chia sẻ lưu trữ, vì vậy tôi là một chút tại một mất mát. Bất cứ ai có bất cứ lời đề nghị hữu ích?

+0

Câu trả lời dưới đây đã giúp tôi giải quyết vấn đề tương tự trong WPF (vui lòng đánh dấu nó là câu trả lời!). Tuy nhiên, để phát triển web, nó tiết kiệm các vấn đề gỡ rối lẻ nếu bạn chỉ bắt đầu với thử nghiệm cục bộ trên IIS thay vì Cassini - bất cứ điều gì nhận được môi trường sản xuất/thử nghiệm/dev của bạn giống như có thể tiết kiệm nỗi buồn trong thời gian dài. – Ted

+0

Tha trả lời dưới đây cũng giải quyết được vấn đề của tôi: NLog + Ninject không làm việc trên chế độ Release khi chế độ Debug hoạt động ok. – Dariusz

Trả lời

34

Bạn có thể tránh sử dụng LogManager.GetCurrentClassLogger() và để Ninject giải quyết tên lớp hiện tại dành cho bạn:

Thay đổi constructor của lớp NLogLogger của bạn vào đây:

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

Và thay đổi Ninject ràng buộc để giải quyết hiện nay classname:

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

Lợi ích bổ sung: tệp nhật ký của bạn bây giờ cũng bao gồm tên lớp từ nơi chỉ thị nhật ký là ued.

Tôi biết câu trả lời của tôi hơi trễ một chút, nhưng tôi đã đấu tranh với bản thân mình ngày hôm nay và không thể tìm thấy câu trả lời ở bất cứ đâu. Có lẽ điều này giúp người khác.

+0

Câu trả lời của bạn đã giúp tôi tìm ra giải pháp StructureMap: http://stackoverflow.com/questions/4519261/nlog-getcurrentclasslogger-nullreferenceexception-using-structuremap-full-trus/4525456#4525456 –

+0

Cảm ơn Robin rất nhiều thực sự hữu ích. Tôi đã mất gần một ngày tách tóc của tôi cố gắng để tìm ra nguyên nhân của một lỗi mà tôi đã nhận được chỉ trên chế độ Release –

+0

Cảm ơn. Tôi cũng nhận được lỗi này chỉ trong bản phát hành Bản phát hành. –

1

Shared lưu trữ thường có hạn chế đối với phản ánh, vv

Vì vậy, tôi đoán là

[NullReferenceException:. Object tài liệu tham khảo không được đặt để một thể hiện của một đối tượng] NLog.LogManager.GetCurrentClassLogger () +84

có liên quan đến điều đó - điều gì sẽ xảy ra nếu bạn nhận được logger bằng cách sử dụng chủ nghĩa meachanism nơi bạn truy cập vào số Type mà bạn nhận được lúc biên dịch qua typeof?

+0

Một trong những lý do tôi chọn chủ nhà (ngoài nhóm giá rẻ - phi lợi nhuận và mọi thứ) là họ được cho là không có bất kỳ hạn chế nào về những thứ như thế. Tôi cũng không phải là một guru NLog bởi bất kỳ phương tiện, nhưng sự hiểu biết của tôi là phương pháp bạn trích dẫn là cách để sử dụng nó, xem http://nlog-project.org/wiki/Tutorial#Creating_loggers ví dụ ... Tôi ' ll có một cái nhìn vào nó khi tôi nhận được nhà ... – Jon

+0

@ Jon: Giống như phần còn lại của hành tinh, tôi đã sử dụng phần của tôi logger (và xấu hổ của tôi bằng văn bản một số). Tôi vừa mới sử dụng log4net và nội dung dựng sẵn trên .NET, chứ không phải NLog - nhưng tôi có kiến ​​thức sâu về cách hoạt động của nó với lo4net và tất cả nó đều rất dễ dàng. Nhìn vào bài báo được trích dẫn, họ có một nơi bạn vượt qua một tên và một nơi mà bạn không. Cái mà bạn không cần phải xác định cái tên bằng cách nào đó - bằng cách nào đó là Reflection. Một số phản ánh (không phải tất cả) bị hạn chế trong lưu trữ được chia sẻ. Do đó, việc xóa 'GetCurrentClassLogger' khỏi phương trình có thể loại bỏ nguyên nhân có thể xảy ra này khỏi các yêu cầu của bạn. –

5

Dường như NLog không thể chạy trong niềm tin vừa: http://nlog-project.org/forum.html#nabble-td1685352

Nếu bạn nhìn vào toàn cầu, các bản ghi ứng dụng khi nó khởi động cũng như khi nó tắt. Bạn sẽ có thể loại bỏ điều đó và hạnh phúc.

+0

Điều này đã được giải quyết bằng NLog ver. 4.4.1 –

0

Tôi đã gặp phải sự cố tương tự.

của tôi (đơn giản) giải pháp:

thay thế những dòng

private Logger Logger = LogManager.GetCurrentClassLogger(); 

bởi dòng này

private static Logger Logger = LogManager.GetCurrentClassLogger(); 

Từ khóa readonly là không bắt buộc.