Thursday, February 3, 2011

ASP.NET MVC3 Html.RenderAction infinite loop / stackoverflow

I have started learning some Asp.net MVC and recently switched over to the MVC3 Razor view engine. I was trying to generate a menu from a controller action and use it on my Layout page so that it was viewable to all pages. So I created a NavController and a Menu() action method with corresponding view. For simplicity, the action just passed an IEnumerable model to the view, which it used to form an unordered list of action links.

I then used Html.RenderAction in the Layout page to render the menu. To my surprise, I got a stack overflow. Upon debugging i realized that it was looping over the action method again and again.

It turns out...and I'm assuming this is Razor specific but have no idea... that if you return a ViewResult from your action method, it will reference the Layout page and call the RenderAction method again. Which returns another ViewResult and references the Layout page again. And again. And again. Until it causes a crash.

The solution was to return a PartialViewResult from the Menu() action, instead of ViewResult. This eliminated the infinite loop and correctly rendered my menu.


10 comments:

Nick said...

Thanks, I had a near identical problem that showed up when code was ported from ASP.NET MVC 2 to MVC 3 and switched to the Razor view engine.

toms98033 said...

Thanks! that solved my problem.

It appeared when I was trying to write Sanderson's Sports Store example in MVC3. I'm glad you did it before me.

schlingel said...

Thank you very much! I was trying to render a menu just like in the SportsStore example, where I ran into the same problem. Thanks for solving. I think I would never figure out what to do.

Nicolas Andres said...

Not working for my.

The menu not appears

Nicolas Andres said...

Ok

I was working with:

@foreach (var link in Model) {
@Html.RouteLink(link.Text, link.RouteValues)
}

in the Menu.cshtml, but the menu appears in blank. I add the < div > following:

@foreach (var link in Model) {
< div >@Html.RouteLink(link.Text, link.RouteValues)< /div >
}

And Working!! YEA!

Argg said...

Thank you for posting this. It was driving me crazy trying to figure out what was going on.

2rock said...

Thanks so much! I was having the exact same issue

Mike Hanrahan said...

Thanks for the tip! Just saved me the good deal of time it would have taken for me to figure that out!

Jason Gerstorff said...

Thanks for the comments glad to help. I've been doing heavy MVC 3 development for the last 8 months I will try to post some more helpful items in the future now that I see they might actually be useful to someone.

Daniel said...

I also had issues with this and this solved it. However I also had the issue Nicolas Andres had. My solution is to add @ infront of Html.RenderAction. I.e.:

@Html.RouteLink(link.Text, link.RouteValues);