Ajuda ASP.NET MVC3 Razor Sintaxe - Estou ficando preso em um loop infinito
-
27-09-2019 - |
Pergunta
Estou tentando converter um pequeno aplicativo MVC2 na sintaxe do MVC3 Razor. No meu aplicativo MVC2, estou usando o mecanismo ASPX View com uma página mestre. Seguindo o exemplo do livro Pro MVC2 de Steven Sanderson, 2ª edição, na página Masterpage, chamo uma ação do controlador que torna uma visão parcial para cada entidade. Isso está funcionando corretamente.
<div id="categories">
<% Html.RenderAction("Menu", "Nav"); %>
</div>
Usando _layout.cshtml e Razor estou tentando isso. Aqui é onde entra meu problema.
<div id="categories">
@{
Html.RenderAction("Menu", "Nav");
}
</div>
Isso está causando um loop infinito agora e estou ficando com uma faixa o suficiente uma StackOverflowException. Alguém pode me ajudar a corrigir o problema? Aqui está o código do método do controlador.
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);
}
Qualquer ajuda ou dicas é mais apreciada.
Obrigado,
~ ck em San Diego
Solução
Você não postou o rastreamento real da pilha, mas, pela descrição, acho que sua recursão está na visualização de ação 'parcial' que executa a página de layout, que renderiza a ação, o que renderiza o layout, etc.
Tente devolver um PartialView
do seu método de ação infantil em vez de um View
. Isso impedirá que a página _Viewstart seja executada, o que impedirá que o layout seja renderizado para sua ação infantil. Mais discussão sobre isso está aqui: http://forums.asp.net/t/1624687.aspx
Outras dicas
colocar
@{
Layout = string.Empty;
}
no topo da sua visão parcial.
Antes de tudo, o parâmetro PersonID nunca é usado (ele é roteado corretamente de qualquer maneira)?
Mas eu definitivamente começaria olhando nos enumeráveishelpers.makelinks é o melhor lugar para um problema de recursão para esconder tentar definir um ponto de interrupção lá
Porque pelo que usei
Modelo :
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; }
}
}
Visão
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; }
}
}
Controlador
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);
}
renderizado
Textocontrolador
Ação em casa
controlador
ActionPerson
Personid1 Carley
controlador
ActionPerson
Personid2 Mark
Tente fazer exatamente isso (em vez de renderização)
@Html.Action("Menu", "Nav")
O que está na sua exibição de menu? Existe algo que possa estar causando uma recursão?