2015-06-04 33 views
6

Mam bardzo dziwny problem z StructureMap.MVC5StructureMap rzuca ArgumentNullException na HttpContext

stworzyłem nowy projekt MVC5 w Visual Studio (opcje domyślne dla projektu ASP.net MVC pozostało zaznaczone.)

Następnie zainstalowałem structuremap.mvc5 za pośrednictwem menedżera pakietów nuget (Install-Package StructureMap.MVC).

I dodaje następujący kod do góry "HomeController.cs" file:

namespace TestMVC.Controllers 
{ 
    public interface ITest 
    { 
     string TestMessage(); 
    } 
    public class Test : ITest 
    { 
     public string TestMessage() 
     { 
      return "this worked again 23"; 
     } 
    } 

I dodaje konstruktor i prywatnym Państwa następująco:

public class HomeController : Controller 
{ 
    private readonly ITest _test; 

    public HomeController(ITest test) 
    { 
     _test = test; 
    } 

Wreszcie, Zaktualizowałem wynik akcji O akcji w następujący sposób:

public ActionResult About() 
{ 
    ViewBag.Message = _test.TestMessage(); 

    return View(); 
} 

Projekt jest kompilowany i uruchamiany. Otrzymuję domyślną stronę indeksu jak zwykle, ale potem gdzieś pomiędzy 2 a 5 sekund po zwróceniu strony w przeglądarce, otrzymuję wyjątek zgłoszony w "StructureMapDependencyScope.cs" na linii return tej metody:

private HttpContextBase HttpContext { 
    get { 
     var ctx = Container.TryGetInstance<HttpContextBase>(); 
     return ctx ?? new HttpContextWrapper(System.Web.HttpContext.Current); 
    } 
} 

dokładny błąd podane jest:

System.ArgumentNullException was unhandled by user code 
    HResult=-2147467261 
    Message=Value cannot be null. 
Parameter name: httpContext 
    ParamName=httpContext 
    Source=System.Web 
    StackTrace: 
     at System.Web.HttpContextWrapper..ctor(HttpContext httpContext) 
     at TestMVC.DependencyResolution.StructureMapDependencyScope.get_HttpContext() in d:\Code\Annies\AnniesV4\AnniesV4-BookingAdministration\TestMVC\DependencyResolution\StructureMapDependencyScope.cs:line 69 
     at TestMVC.DependencyResolution.StructureMapDependencyScope.get_CurrentNestedContainer() in d:\Code\Annies\AnniesV4\AnniesV4-BookingAdministration\TestMVC\DependencyResolution\StructureMapDependencyScope.cs:line 55 
     at TestMVC.DependencyResolution.StructureMapDependencyScope.DisposeNestedContainer() in d:\Code\Annies\AnniesV4\AnniesV4-BookingAdministration\TestMVC\DependencyResolution\StructureMapDependencyScope.cs:line 90 
     at TestMVC.DependencyResolution.StructureMapDependencyScope.Dispose() in d:\Code\Annies\AnniesV4\AnniesV4-BookingAdministration\TestMVC\DependencyResolution\StructureMapDependencyScope.cs:line 85 
     at TestMVC.App_Start.StructuremapMvc.End() in d:\Code\Annies\AnniesV4\AnniesV4-BookingAdministration\TestMVC\App_Start\StructuremapMvc.cs:line 44 
    InnerException: 

Sprawdzanie, System.Web.HttpContext.Current rzeczywiście jest zerowa w tym momencie.

Jeśli zatrzymam się i zrestartuję projekt, wystąpi ten sam błąd.
Po naciśnięciu klawisza F5, aby kontynuować, strona internetowa nadal działa zgodnie z oczekiwaniami.
Jeśli jednak po naciśnięciu klawisza F5, zaczekaj kilka chwil, zatrzymaj i zrestartuj projekt, nie otrzymam ponownie błędu, dopóki nie dokonam jakiejś zmiany kodu i nie odbuduję go!

To pozornie nie ma dla mnie sensu!

Anyways .. każda pomoc byłaby doceniona!

(Enterprise Korzystanie VS2015 RC jeśli czyni żadnej różnicy)

Odpowiedz

5

Problem jest w wyrzucać pojemnika. Próbuje wyrzucić zagnieżdżony kontener, który żyje w HttpContext, który jest zerowy w momencie usuwania.

Zrobiłem to zmian w klasie StructureMapDependencyScope w celu uniknięcia tego wyjątku:

public IContainer CurrentNestedContainer 
{ 
    get 
    { 
     if (HttpContext == null) 
      return null; 

     return (IContainer)HttpContext.Items[NestedContainerKey]; 
    } 
    set 
    { 
     HttpContext.Items[NestedContainerKey] = value; 
    } 
} 

private HttpContextBase HttpContext 
{ 
    get 
    { 
     var ctx = Container.TryGetInstance<HttpContextBase>(); 
     if (ctx == null && System.Web.HttpContext.Current == null) 
      return null; 

     return ctx ?? new HttpContextWrapper(System.Web.HttpContext.Current); 
    } 
}