2011-01-01 8 views
1

Ich habe eine ASP.NET MVC 3-Webanwendung, die Jonathan McCrackens Test-Drive Asp.NET MVC folgt (tolles Buch, übrigens) und ich bin auf ein Problem gestoßen. Beachten Sie, dass ich MVCContrib, Rhino und NUnit verwende.Versucht, geschützten Speicher zu lesen oder zu schreiben

[Test] 
    public void ShouldSetLoggedInUserToViewBag() { 
     var todoController = new TodoController(); 
     var builder = new TestControllerBuilder(); 
     builder.InitializeController(todoController); 

     builder.HttpContext.User = new GenericPrincipal(new GenericIdentity("John Doe"), null); 

     Assert.That(todoController.Index().AssertViewRendered().ViewData["UserName"], Is.EqualTo("John Doe")); 
    } 

Der obige Code immer wirft diesen Fehler:

System.AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Der Controller Aktionscode ist die folgende:

[HttpGet] 
    public ActionResult Index() { 
     ViewData.Model = Todo.ThingsToBeDone; 
     ViewBag.UserName = HttpContext.User.Identity.Name; 

     return View(); 
    } 

Von dem, was ich herausgefunden haben, die App, weil zum Absturz zu bringen scheint, der beiden Aufgaben in der Controller-Aktion. Allerdings kann ich nicht sehen, wie es falsch ist !?

Kann mir jemand helfen, die Lösung für dieses Problem zu finden.

Vielen Dank.

Edit 1

Ich habe einige Experimente durchgeführt, um zu sehen, was das Problem ist. Beim Entfernen der ViewData,Model Zuweisung überschreitet das Problem Expected result to be of type ViewResult. It is actually of type ViewResult.. Die ViewData Zuordnung ist so grundlegend, dass ich glaube nicht, dass es das Problem ist, also denke ich, dass etwas mit Rhino oder MVCcontrib in Verbindung mit MVC 3 nicht stimmt.

Ich habe auch den folgenden Test früher für den gleichen Controller geschrieben Aktion:

 [Test] 
    public void ShouldDisplayAListOfTodoItems() { 
     Assert.That(((ViewResult)new TodoController().Index()).ViewData.Model, Is.EqualTo(Todo.ThingsToBeDone)); 
    } 

dieser scheitert nun mit System.NullReferenceException : Object reference not set to an instance of an object becuase wahrscheinlich gibt es keine Httpcontext für diesen speziellen Test einrichten. Wenn Sie die ViewBag Zuweisung entfernen, ist alles in Ordnung.

Hoffnung, die das Problem klarer macht.

bearbeiten 2

Wenn Sie den Code debuggen, nachdem die ViewData.Model Zuordnung zu entfernen, wirft es einen anderen Fehler: System.NullReferenceException : Object reference not set to an instance of an object. auf der ViewBag Zuordnung.

+0

Auf welcher Zeile genau wird die Ausnahme ausgelöst und können Sie die vollständige Stack-Trace buchen? –

+0

Nun, es stirbt, wenn ich versuche, den ViewData etwas zuzuweisen. Also, wenn ich die zwei Zeilen kommentiere, wo ich ViewData und ViewBag Sachen gebe, stirbt es nicht. – Interfector

Antwort

5

Nun, ich habe diesen hier niedergeschlagen. Wie ich vermutet habe, lag es an MVCContrib. Beachten Sie, dass ich MVC 3 Beta verwende, das von MVCContrib noch nicht offiziell unterstützt wird. Vor diesem Hintergrund habe ich die neuesten MVCContrib-Quellen für den MVC 3-Zweig heruntergeladen.

Gehen Sie zu MVCContrib Sources, wechseln Sie zum mvc3 Zweig, laden Sie die Binärdateien mit dem angehängten Schläger herunter und bauen Sie sie auf.Fügen Sie dann die benötigten Dateien in Ihre Lösung ein.

Nun, das wird wahrscheinlich in einer zukünftigen stabilen Version behoben werden, aber ich denke, es könnte für andere nützlich sein. Vielen Dank für Ihr Interesse.

+0

LEBENSRETTER (Zeitraum) ... Danke. – AJC

1

Wie wäre es damit:

[Test] 
public void ShouldSetLoggedInUserToViewBag() 
{ 
    // arrange 
    var todoController = new TodoController(); 
    var builder = new TestControllerBuilder(); 
    builder.InitializeController(todoController); 

    builder.HttpContext 
     .Stub(x => x.User) 
     .Return(new GenericPrincipal(new GenericIdentity("John Doe"), null)); 

    // act 
    var actual = todoController.Index(); 

    // assert 
    actual.AssertViewRendered(); 
    Assert.That(todoController.ViewData["UserName"], Is.EqualTo("John Doe")); 
} 

und die Controller-Aktion:

[HttpGet] 
public ActionResult Index() 
{ 
    ViewBag.UserName = HttpContext.User.Identity.Name; 
    return View(Todo.ThingsToBeDone); 
} 

Bemerkung: Ich würde die Informationen in das Ansichtsmodell enthalten und vermeiden ViewData/ViewBag verwenden. Es ist nicht stark typisiert und es zwingt Sie, magische Zitate zu verwenden.

+0

Ich werde versuchen, Ihren Code so schnell wie möglich und kommen Sie auf das Ergebnis zurück. ViewBag ist dynamisch und erfordert kein Angebot. Es ist eine neue Ergänzung zu MVC 3. – Interfector

+0

Nein, funktioniert nicht. Es wird die folgende Fehlermeldung ausgegeben: Sie versuchen, eine Erwartung für eine Eigenschaft festzulegen, die für die Verwendung von PropertyBehavior definiert wurde. Anstatt Code wie folgt zu schreiben: mockObject.Stub (x => x.SomeProperty) .Return (42); Sie können die Eigenschaft direkt verwenden, um dasselbe Ergebnis zu erzielen: mockObject.SomeProperty = 42; – Interfector

+0

@Intersektor, richtig, also irre ich mich. Was passiert, wenn Sie es wie in Ihrem Beispiel direkt zuweisen? Auch wenn Sie ViewBag/ViewData nicht mehr in Ihrer Controller-Aktion verwenden. Könnten Sie versuchen, das Problem zu isolieren? –