У меня есть один нормальный вид (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
Спасибо за любую помощь или подсказки по этой проблеме.
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}})
HtmlHelper
который просматривает текущие значения маршрута вhtmlHelper.ViewContext.RouteData.Values
и очищает их (возможно, сохраняя контроллер и действие?) Перед вызовом существующего методаAction