ASP.NET MVC3 Razor syntax help - I'm getting stuck in an infinite loop
-
27-09-2019 - |
문제
I'm trying to convert a small mvc2 application to the mvc3 razor syntax. In my mvc2 application I'm using the aspx view engine with a master page. Following the example from Steven Sanderson's Pro MVC2 book 2nd edition, in the masterpage I call a controller action that renders a partial view for each entity. This is working correctly.
<div id="categories">
<% Html.RenderAction("Menu", "Nav"); %>
</div>
using _layout.cshtml and razor I'm trying this. Here is where my problem comes in.
<div id="categories">
@{
Html.RenderAction("Menu", "Nav");
}
</div>
This is causing an infinite loop now and I'm getting oddly enough a StackOverflowException. Can anyone help me correct the problem? Here is the controller method code.
public ViewResult Menu(string personId)
{
Func<string, NavLink> makeLink = pId => new NavLink
{
Text = pId ?? "Home"
, RouteValues = new RouteValueDictionary(new { controller = "Person", action = "Person"})
};
List<NavLink> navLinks = new List<NavLink> {makeLink(null)};
Func<Person, NavLink> makeLink2 = p => new NavLink
{
Text = p.Name ?? "Home"
, RouteValues = new RouteValueDictionary(new { controller = "Person", action = "Person", personId = p.Id })
};
var people = usersRepository.People.OrderBy(x => x.Name);
var peopleLinks = EnumerableHelpers.MakeLinks(people, makeLink2);
navLinks.AddRange(peopleLinks);
return View("_menu", navLinks);
}
Any help or tips is most appreciated.
Thanks,
~ck in San Diego
해결책
You didn't post the actual stack trace, but from the description I'm guessing your recurssion is in the 'partial' action view running the layout page, which renders the action, which renders the layout, etc.
Try returning a PartialView
from your child action method instead of a View
. This will prevent the _ViewStart page from being executed which will prevent the layout from being rendered for your child action. More discussion about this is here: http://forums.asp.net/t/1624687.aspx
다른 팁
put
@{
Layout = string.Empty;
}
in top of your partial View .
first of all your personId parameter is never used (is it routed correctly anyway)?
but I would definitely start by looking in the EnumerableHelpers.MakeLinks it is the best place for a recursion problem to hide try setting a breakpoint there
because from what I used
Model :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MvcApplication1.Controllers
{
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class EnumerableHelpers
{
internal static List<NavLink> MakeLinks(IOrderedEnumerable<Person> people, Func<Person, NavLink> makeLink2)
{
var retVal = new List<NavLink> ();
foreach (var item in people)
{
retVal.Add(makeLink2(item));
}
return retVal;
}
}
public class usersRepository
{
private static List<Person> people = new List<Person>();
public usersRepository()
{
}
public static List<Person> People
{
get
{
people = new List<Person>() {
new Person() { Id = 1, Name = "carley" },
new Person() { Id = 2, Name = "mark" },
};
return people;
}
set
{
people = value;
}
}
}
public class NavLink
{
public System.Web.Routing.RouteValueDictionary RouteValues { get; set; }
public string Text { get; set; }
}
}
View
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MvcApplication1.Controllers
{
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class EnumerableHelpers
{
internal static List<NavLink> MakeLinks(IOrderedEnumerable<Person> people, Func<Person, NavLink> makeLink2)
{
var retVal = new List<NavLink> ();
foreach (var item in people)
{
retVal.Add(makeLink2(item));
}
return retVal;
}
}
public class usersRepository
{
private static List<Person> people = new List<Person>();
public usersRepository()
{
}
public static List<Person> People
{
get
{
people = new List<Person>() {
new Person() { Id = 1, Name = "carley" },
new Person() { Id = 2, Name = "mark" },
};
return people;
}
set
{
people = value;
}
}
}
public class NavLink
{
public System.Web.Routing.RouteValueDictionary RouteValues { get; set; }
public string Text { get; set; }
}
}
Controller
public ViewResult Menu(string id)
{
Func<string, NavLink> makeLink = pId => new NavLink
{
Text = pId ?? "Home"
,
RouteValues = new RouteValueDictionary(new { controller = "Person", action = "Person" })
};
List<NavLink> navLinks = new List<NavLink> { makeLink(null) };
Func<Person, NavLink> makeLink2 = p => new NavLink
{
Text = p.Name ?? "Home"
,
RouteValues = new RouteValueDictionary(new { controller = "Person", action = "Person", personId = p.Id })
};
var people = usersRepository.People.OrderBy(x => x.Name);
var peopleLinks = EnumerableHelpers.MakeLinks(people, makeLink2);
navLinks.AddRange(peopleLinks);
return View(navLinks);
}
rendered
TextcontrollerPerson
actionPerson Home
controllerPerson
actionPerson
personId1 carley
controllerPerson
actionPerson
personId2 mark
Try doing just this (instead of RenderAction)
@Html.Action("Menu", "Nav")
What is in your menu view? Is there anything that could be causing a recursion?