在 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"。
我之前一直在使用 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"。