1

У меня есть один нормальный вид (NV) и 2 частичных вида (PV1 и PV2), PV2 вложен в PV1, а PV1 - в NV. Проблема, с которой я сталкиваюсь, заключается в том, что PV1 и PV2 имеют необязательный пентаметр с именем «isSuccessful», который добавляется в сумку View «ViewBag.IsSuccessful = isSuccessful;» в действии, и по какой-то причине, когда PV1 имеет свой «isSuccessful», установленный в true, PV2 «isSuccessful» также привязан к истине. Это приводит к тому, что PV2 запускает некоторые функции JavaScript, преждевременно вызывая другие проблемы.предотвратить действие дочернего объекта от привязки к родительскому объекту ViewData

Код (структура и пример)

в контроллере

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); 
    } 

The Views

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, C# и .NET 4.5

Спасибо за любую помощь или подсказки по данному вопросу.

ответ

1

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

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

Если вы проверите MVC source code для помощника 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, который позволил бы установить параметр маршрута в нуль:

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

Хорошо, что интересно.Интересно, могу ли я расширить или написать помощник для эфира, чтобы проехать эту функциональность или, по крайней мере, добавить bool-коляску, которая предотвращает слияние или что-то? спасибо –

+0

Вы можете создать свой собственный метод расширения HtmlHelper, который будет смотреть на текущий значения маршрута в 'htmlHelper.ViewContext.RouteData.Values' и очищает их (возможно, поддерживает контроллер и действие?) перед вызовом существующего метода« Действие » –

Смежные вопросы