我正在尝试实现一个想法,我必须允许为我的MVC 3 Razor站点动态生成用户定义的部分。
模板看起来像这样
<div class="sidebar">
@RenderSection("Sidebar", false)
</div>
<div class="content">
@RenderSection("MainContent", false)
@RenderBody()
</div>
使用以下代码添加视图会给出我期望的结果
DefineSection("MainContent", () =>
{
this.Write("Main Content");
});
DefineSection("Sidebar", () =>
{
this.Write("Test Content");
});
输出:
<div class="sidebar">Test Content </div>
<div class="content">Main Content <p>Rendered body from view</p></div>
看着这个,创建一个模型似乎很容易
Dictionary<SectionName, Dictionary<ControlName, Model>>
var sectionControls = new Dictionary<string, Dictionary<string, dynamic>>();
sectionControls.Add("MainContent", new Dictionary<string, dynamic>()
{
{"_shoppingCart", cart}
});
sectionControls.Add("Sidebar", new Dictionary<string, dynamic>()
{
{ "_headingImage", pageModel.HeadingImage },
{ "_sideNav", null }
});
pageModel.SectionControls = sectionControls;
因此,上面的代码声明了两个模板部分(带有购物车的“MainContent”和带有图像和导航的“侧边栏”。
所以现在我的视图包含了如此呈现输出的代码
foreach(KeyValuePair<string,Dictionary<string,dynamic>> section in Model.SectionControls)
{
DefineSection(section.Key, () =>
{
foreach (KeyValuePair<string, dynamic> control in section.Value)
{
RenderPartialExtensions.RenderPartial(Html, control.Key, control.Value);
}
});
}
现在,当我运行此代码时,两个部分都包含相同的内容!单步执行代码显示加载路径如下
操作返回,上面的代码在View中运行,LayoutTemlpate开始加载。当在布局模板中为这两个部分调用RenderSection时,视图再次运行!对我来说似乎更奇怪的是,最终结果是“HeadingImage”和“SideNav”最终都出现在Sidebar和MainContent部分。 MainContent部分不包含购物车,它包含侧边栏部分的副本。
<div class="sidebar">
<h2><img alt=" " src="..."></h2>
..nav..
</div>
<div class="content">
<h2><img alt=" " src="..."></h2>
..nav..
<p>Rendered body from view</p>
</div>
注释掉Controller中两个部分定义中的一个导致另一个部分是唯一的项目(但它仍然是重复的!)
之前是否有人遇到此问题或知道可能导致此行为的限制?
编辑:非常好。感谢您的联系!我正在为剃须刀支持的新版resharper而受伤。
答案 0 :(得分:6)
您的lambda表达式共享相同的section
变量
当调用lambda时,变量的当前值是最后一节。
You need to declare a separate variable inside the loop
foreach(KeyValuePair<string,Dictionary<string,dynamic>> dontUse in Model.SectionControls)
{
var section = dontUse;
DefineSection(section.Key, () =>
{
foreach (KeyValuePair<string, dynamic> control in section.Value)
{
RenderPartialExtensions.RenderPartial(Html, control.Key, control.Value);
}
});
}