[英]prevent child action from binding to parent ViewData
我有一个普通视图(NV)和2个局部视图(PV1和PV2),PV2嵌套在PV1中,PV1嵌套在NV中。 我遇到的问题是PV1和PV2都有一个可选的五角表,称为“ isSuccessful”,已添加到视图包“ ViewBag.IsSuccessful = isSuccessful;”中。 在动作中,由于某种原因,PV1的“ isSuccessful”设置为true PV2的“ isSuccessful”也绑定为true。 这导致PV2过早运行某些JavaScript函数,从而导致其他问题。
代码(结构和示例)
在控制器中
public ActionResult NV(int id)
{
var model = GetNVModel(id);
return View(model);
}
public ActionResult PV1 (int pv1Id = 0, bool isSuccessful = false)
{
var model = GetPV1Model(id);
ViewBag.IsSuccessful = isSuccessful;
return PartialView(model);
}
public ActionResult PV2 (int pv2Id = 0, bool isSuccessful = false)
{
var model = GetPV2Model(id);
if(model == null){model = new PV2Model();}
ViewBag.IsSuccessful = isSuccessful;
return PartialView(model);
}
观点
NV.cshtml
@model NVModel
<div>
@if (Model != null && Model.PV1Id != null && Model.PV1Id > 0)
{<text>
@Html.Action("PV1", "ControlerName", new { PV1Id = Model.PV1Id, isSuccessful = true})
</text>}
</div>
PV1.cshtml
@model PV1Model
@{bool isSuccessful = (ViewBag.IsSuccessful != null ? (bool)ViewBag.IsSuccessful : false);}
<div>
@if (Model != null && Model.PV2Id != null && Model.PV2Id > 0)
{<text>
@Html.Action("PV2", "ControlerName", new { PV2Id = Model.PV2Id })
</text>}
</div>
<script>
@if (isSuccessful )
{<text>
function sayHello()
{console.log('Hello PV1');}
</text>}
</script>
PV2.cshtml
@model PV2Model
@{bool isSuccessful = (ViewBag.IsSuccessful != null ? (bool)ViewBag.IsSuccessful : false);}
<div>
@if (Model != null)
{<text>
@Html.TextBoxFor(model=> model.Message)
</text>}
</div>
<script>
@if (isSuccessful )
{<text>
$(document).ready(function(){
console.log($("#Message").val());
});
</text>}
</script>
我不明白的是为什么将PV1的ViewData / ViewBag传递给PV2。 我认为不传递所有父ViewData / ViewBag是在“ @ Html.Partial”上使用“ @ Html.Action”的部分原因。 我需要知道的是,是否有一个参数需要传递给“ @ Html.Action”或需要翻转一个web.config属性 ,因为以上内容不仅是一次性的,这是我的一种方式。为了使视图尽可能灵活,我做了大部分页面。
我正在使用ASP.NET MVC 4,C#和.NET 4.5
感谢您对这个问题的任何帮助或线索。
动作之间不共享ViewBag,但是路由参数是共享的! 如果在PV2
方法内设置了一个断点并在执行ViewBag.IsSuccessful = isSuccessful;
之前检查了ViewBag,则可以看到此信息ViewBag.IsSuccessful = isSuccessful;
。 您将看到ViewBag为空,但是该方法收到的参数为true。
问题是您要通过@Html.Action("PV1", "ControlerName", new { PV1Id = Model.PV1Id, isSuccessful = true})
将路由参数isSuccessful
传递给PV1,因此当您调用PV2操作时,路由属性PV2与当前的合并。 这意味着isSuccessful将传递给PV2。
如果检查Html.Action
帮助器的MVC源代码 ,则会看到路由属性已与当前属性合并。 检查内部ActionHelper
方法,其中发生合并:
internal static void ActionHelper(HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, TextWriter textWriter)
{
...
//The route values provided to @Html.Action are merged with the current ones
RouteValueDictionary additionalRouteValues = routeValues;
routeValues = MergeDictionaries(routeValues, htmlHelper.ViewContext.RouteData.Values);
...
}
如果要防止这种情况,可以在调用PV2时覆盖route参数。 为此,您可以执行以下操作:
@Html.Action("PV2", "Home", new { isSuccessful = "" })
您还可以使用RouteValueDictionary
调用该操作,该操作可让您将route参数设置为null:
@Html.Action("PV2", "Home", new RouteValueDictionary{{"isSuccessful", null}})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.