阻止子操作绑定到父ViewData

本文关键字:ViewData 绑定 操作 | 更新日期: 2023-09-27 18:28:42

我有一个正常视图(NV)和两个局部视图(PV1和PV2),PV2嵌套在PV1中,PV1在NV中。我遇到的问题是,PV1和PV2都有一个名为"isSuccessful"的可选五音表,该五音表在操作中添加到View包"ViewBag.isSuccessful=isSuccessfull;"中,并且由于某种原因,当PV1的"isSucceful"设置为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.Action"而不是"@Html.Partial"的一部分。我需要知道的是,是否有一个参数需要传递给"@Hml.Action",或者是否需要翻转web.config属性,因为以上内容不仅仅是一次性的,这是我大部分页面的处理方式,目的是使视图尽可能灵活。

我使用的是ASP.NET MVC 4、C#和.NET 4.5

感谢您对此问题的任何帮助或线索。

阻止子操作绑定到父ViewData

ViewBag不是在操作之间共享的,但是路由参数是!如果在PV2方法内部设置断点,并在执行ViewBag.IsSuccessful = isSuccessful;之前检查ViewBag,则可以看到这一点。您将看到ViewBag为空,但该方法接收到的参数为true。

问题是,将路由参数isSuccessful@Html.Action("PV1", "ControlerName", new { PV1Id = Model.PV1Id, isSuccessful = true})一起传递给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时替代管线参数。为此,您可以执行以下操作:

@Html.Action("PV2", "Home", new { isSuccessful = "" })

您也可以使用RouteValueDictionary调用该操作,这将允许您将路由参数设置为null:

@Html.Action("PV2", "Home", new RouteValueDictionary{{"isSuccessful", null}})