Attempted to read or write protected memory
Asked Answered
V

2

1

I have a sample ASP.NET MVC 3 web application that is following Jonathan McCracken's Test-Drive Asp.NET MVC (great book , by the way) and I have stumbled upon a problem. Note that I'm using MVCContrib, Rhino and NUnit.

    [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"));
    }

The code above always throws this error:

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

The controller action code is the following:

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

        return View();
    }

From what I have figured out, the app seems to crash because of the two assignements in the controller action. However, I cannot see how there are wrong!?

Can anyone help me pinpoint the solution to this problem.

Thank you.

Edit 1

I've done some experiments to see what the problem is. When removing the ViewData,Model assignment the problem transcends in Expected result to be of type ViewResult. It is actually of type ViewResult.. The ViewData assignment is so basic that I do not think that it is the problem so I think there is something wrong with either Rhino or MVCcontrib in conjunction with MVC 3.

I also have the following test written earlier for the same controller action:

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

This one fails now with System.NullReferenceException : Object reference not set to an instance of an object probably becuase there's no HttpContext set up for this particular test. When removing the ViewBag assignment, everything is ok.

Hope that makes the problem more clear.

Edit 2

When debugging the code after removing the ViewData.Model assignment, it throws a different error: System.NullReferenceException : Object reference not set to an instance of an object. on the ViewBag assignment.

Vernation answered 1/1, 2011 at 23:9 Comment(2)
On which line exactly is the exception thrown and could you post the full stack trace?Thornhill
Well, it dies when I try to assign something into the ViewData. So, if I comment the two lines where I assign stuff to ViewData and ViewBag it does not die.Vernation
V
5

Well, I've knocked this one down. As I have suspected, it was because of MVCContrib. Mind that I am using MVC 3 Beta which is not yet officially supported by MVCContrib. With that in mind, I have downloaded the latest MVCContrib sources for MVC 3 branch.

Go to MVCContrib Sources, switch to the mvc3 branch, download, and build the binaries with the attached bat. Then, include the needed files into your solution.

Well, this will probably get fixed in a future stable release, but I guess it might be useful to others. Thank you Darin for your interest.

Vernation answered 2/1, 2011 at 21:30 Comment(0)
T
1

How about this:

[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"));
}

and the controller action:

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

Remark: I would include the information into the view model and avoid using ViewData/ViewBag. It is not strongly typed and it forces you to use magic quotes.

Thornhill answered 2/1, 2011 at 8:51 Comment(4)
I'll try your code ASAP and get back on you on the result.ViewBag is dynamic, and does not require quoting. It's a new addition to MVC 3.Vernation
Nope, does not work. It throws an error saying that: You are trying to set an expectation on a property that was defined to use PropertyBehavior. Instead of writing code such as this: mockObject.Stub(x => x.SomeProperty).Return(42); You can use the property directly to achieve the same result: mockObject.SomeProperty = 42;Vernation
@Interfector, right, so I am mistaken. What if you assign it directly as you did in your example. Also what if you no longer use ViewBag/ViewData in your controller action. Could you try isolating the problem?Thornhill
See my edit. I think the HttpContext is not setup correctly by MVCContrib.Vernation

© 2022 - 2024 — McMap. All rights reserved.