在 RenderPartial 中设置 ViewData

Set ViewData inside a RenderPartial

我之前一直在使用 TempData 来设置 "body css class" 之类的东西,然后页面和部分可以覆盖。

在意识到 TempData 使用会话后,我现在转移到 ViewData,但是在部分内部设置 ViewDataDictionary 的值在返回到页面时基本上会被忽略 - 并且永远不会向上传播布局层次结构。

我试过从我的页面内部调用 "RenderPartial",并使用允许我指定要传递的 ViewData 的覆盖:

布局:

页数:

@{
    var cssClass = (ViewData["something"] != null) ? ViewData["something"].ToString() : "";
}

<body class="@cssClass">

页数:

@{
    ViewData["something"] = "blah";
    Html.RenderPartial("MyPartial", ViewData)
}

部分:

@{
    ViewData["something"] += " blah";
}

当我在布局内部进行调试时,我可以看到 ViewData["something"] 是 "blah" - 局部设置不正确。

当我使用 TempData 时,这可以正常工作。由于 ASP 会话锁定及其对并发请求的影响,我真的不想回到使用 TempData。

有没有人让这个工作过?我是不是忽略了什么?

谢谢

每个视图都有自己的 ViewData。默认情况下,Razor 会使用其父级的 ViewData 填充视图在层次结构的更下方,但这是单向的。例如,如果您执行以下操作:

SomeView.cshmtl

@{ ViewData["foo"] = "bar"; }
@Html.Partial("_SomePartial")

SomePartial.cshtml

@ViewData["foo"]

部分结果将如您所料 "bar"。但是,如果你做了类似的事情:

SomeView.cshtml

@Html.Partial("_SomePartial")
@ViewData["foo"]

_SomePartial.cshtml

@{ ViewData["foo"] = "bar"; }

不会打印任何内容,因为 ViewData["foo"] 不存在于父视图的视图数据中,仅存在于局部视图数据中。

所以这是一种单向传播,正如您发现的那样,如果您想部分设置数据并 return 到父视图,您可以使用 HttpContext 这不是很酷但它作品:

家长:

@{
    HttpContext.Current.Items["Something"] = "blah";
    Html.RenderPartial("_Partial");
}
@HttpContext.Current.Items["Something"];

部分:

@{
    HttpContext.Current.Items["Something"] = "somethingelse";
}

在父级中输出 "somethingelse"。

或者,如果您绕过 TempData,通常的做法是通过父模型或临时模型:

型号:

public class MyTempModel
{
    public string Something { get; set; }
}

家长:

@{
    var tmod = new MyTemModel()
    {
       Something = "blah"
    };
    Html.RenderPartial("_Partial", tmod);
}
@tmod.Something;

部分:

@model MyTempModel
@{
    tMod.Something = "somethingelse";
}

在父级中输出 "somethingelse"。