【问题标题】:Dynamically Defined Content Sections in Razor ViewsRazor 视图中动态定义的内容部分
【发布时间】:2011-06-14 17:31:35
【问题描述】:

我正在尝试实现一个想法,我必须允许为我的 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&lt;SectionName, Dictionary&lt;ControlName, Model&gt;&gt;

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”带有购物车,“Sidebar”带有图像和导航。

所以现在我的视图包含渲染输出的代码

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

现在,当我运行此代码时,两个部分都包含相同的内容!单步执行代码显示加载路径如下

Action 返回,上面的代码在 View 中运行,LayoutTemplate 开始加载。当在布局模板中为这两个部分调用 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 让我很伤心。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 razor


    【解决方案1】:

    您的 lambda 表达式共享相同的 section 变量。
    当任一 lambda 被调用时,变量的 current 值是最后一部分。

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

    【讨论】:

    • 今天我被咬了,谢谢。我做了更多阅读,发现了这个blogs.msdn.com/b/ericlippert/archive/2009/11/12/…。访问修改后的闭包是我(每个人)都应该理解的事情
    • 除了使用渲染扩展之外,您还可以使用Html.ViewContext.Writer 将您想要的任何内容输出到该部分中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    • 2011-11-25
    相关资源
    最近更新 更多