本文介绍了剃刀视图中的动态定义的内容部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现一个想法,我必须允许为我的MVC 3 Razor网站动态生成用户定义的部分.

I'm trying to implement a thought i had to allow user defined sections to be dynamically generated for my MVC 3 Razor site.

模板看起来像这样

<div class="sidebar">
     @RenderSection("Sidebar", false)
</div>
<div class="content">
     @RenderSection("MainContent", false)
     @RenderBody()
</div>

使用以下代码添加视图会给我期望的结果

Adding a view with the following code gives me the result I would expect

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>>

Looking at this it seemed easy enough to create a modelDictionary<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"和带有图片和导航的"Sidebar".

So the above code declares two template sections ("MainContent" with a cart and a "Sidebar" with an image and a nav.

所以现在我的视图包含代码来渲染输出,就像这样

So now my view contains code to render the output like so

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

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

Now when I run this code, both sections contain the same content! Stepping through the code shows the load path is as follows

动作返回,以上代码在View中运行,LayoutTemlpate开始加载.当在布局模板中为这两个部分调用RenderSection时,视图将再次运行!在我看来,甚至更奇怪的是,最终结果是"HeadingImage"和"SideNav"同时出现在补充工具栏和MainContent部分中. MainContent部分不包含购物车,它包含侧边栏部分的副本.

Action Returns, Code above runs in View, LayoutTemlpate begins to load. when RenderSection is called for these two sections in the layout template, the view Runs again! What seems even stranger to me is that the end result is that the "HeadingImage" and "SideNav" end up in both the Sidebar and MainContent sections. The MainContent section does not contain the cart, it contains a duplicate of the sidebar section.

<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中两个节定义之一,会使另一个成为唯一的项(但它仍然是重复的!)

Commenting out one of the two section definitions in the Controller causes the other one to be the only item (but it is still duplicated!)

任何人以前都曾遇到过此问题,或者知道什么限制可能导致此行为?

Has anyone had this issue before or know what limitation could be causing this behavior?

极好.也感谢您的联系!对于使用剃须刀的新版刮胡刀,我感到很痛苦.

Excellent. Thanks for the linkage as well! I'm hurting for the new version of resharper with razor support.

推荐答案

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

Your lambda expressions are sharing the same section variable.
When either lambda is called, the current value of the variable is the last section.

您需要在循环内声明一个单独的变量.

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

这篇关于剃刀视图中的动态定义的内容部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 16:01