запретить привязку дочернего действия к родительскому ViewData

1

У меня есть один нормальный вид (NV) и 2 частичных вида (PV1 и PV2), PV2 вложен в PV1, а PV1 - в NV. Проблема, с которой я сталкиваюсь, заключается в том, что PV1 и PV2 имеют необязательный пентаметр с именем "isSuccessful", который добавляется в сумку View "ViewBag.IsSuccessful = isSuccessful;" в действии, и по какой-то причине, когда PV1 имеет свой "isSuccessful", установленный в true PV2, isSuccessful также связан с истинным. Это приводит к тому, что 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". Мне нужно знать, есть ли параметр, который мне нужно передать в "@Html.Action", или атрибут web.config нужно перевернуть, потому что выше это не просто одно время, это способ, которым я выполняли большую часть моих страниц, чтобы сделать представления максимально гибкими.

Я использую ASP.NET MVC 4, С# и.NET 4.5

Спасибо за любую помощь или подсказки по этой проблеме.

Теги:
asp.net-mvc
asp.net-mvc-4
asp.net-mvc-partialview

1 ответ

1
Лучший ответ

ViewBag не разделяется между действиями, однако параметры маршрута! Вы можете увидеть это, если вы установите контрольную точку внутри PV2 метода и проверить ViewBag перед выполнением ViewBag.IsSuccessful = isSuccessful; , Вы увидите, что ViewBag пуст, но метод получил параметр как истинный.

Проблема заключается в том, что вы передаете параметр маршрута isSuccessful в PV1 с помощью @Html.Action("PV1", "ControlerName", new { PV1Id = Model.PV1Id, isSuccessful = true}) поэтому, когда вы вызываете действие @Html.Action("PV1", "ControlerName", new { PV1Id = Model.PV1Id, isSuccessful = true}) маршрута для PV2 объединены с текущими. Это означает, что isSuccessful будет передан PV2.

Если вы проверите исходный код MVC для помощника Html.Action, вы увидите, что атрибуты маршрута объединены с текущими. Проверьте внутренний метод 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}})
  • 0
    Хорошо, это интересно. Интересно, могу ли я расширить или написать помощника для эфира через эту функциональность или хотя бы добавить рабочую коляску, которая предотвращает слияние или что-то еще, спасибо
  • 0
    Вы можете создать свой собственный метод расширения HtmlHelper который просматривает текущие значения маршрута в htmlHelper.ViewContext.RouteData.Values и очищает их (возможно, сохраняя контроллер и действие?) Перед вызовом существующего метода Action

Ещё вопросы

Сообщество Overcoder
Наверх
Меню