Параметры метода RenderAction равны нулю после обратной передачи - PullRequest
0 голосов
/ 16 марта 2020

Моя проблема в том, что значения параметров в методе RenderAction GET равны нулю после любой обратной передачи в приложении (см. Ниже). Можете ли вы помочь мне определить проблему или как лучше структурировать код макета? Я подумываю об использовании ViewBag для идентификаторов, а не параметров URL, но сейчас хотелось бы получить более быстрое решение.

_Layout.cs html

<!DOCTYPE html>

<html lang="nl">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
</head>
<body>
    @{ Html.RenderAction("LayoutMenu", "Example", new { pageTitle = ViewBag.Title }); }

    <div class="...">
        @RenderBody()
    </div>
    <footer class="...">
        @* ... *@
    </footer>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")
    @* ... *@
</body>
</html>

_LayoutMenu.cs html

@model namespace.Models.LayoutMenu

<header class="...">
    <div class="">
        <div class="">
            <a href="@Url.Action("Index", "Home")"></a>
        </div>
        @if (Model != null && Model.Entities != null)
        {
            Html.RenderPartial("_Entities", Model.Entities);
        }
        <div class="">
            <nav class="">
                @{
                    var controller = ViewContext.ParentActionViewContext.RouteData.Values["Controller"].ToString();
                    var action = ViewContext.ParentActionViewContext.RouteData.Values["Action"].ToString();
                    var id1 = ViewContext.ParentActionViewContext.RouteData.Values["id1"];
                    var id2 = ViewContext.ParentActionViewContext.RouteData.Values["id2"];
                    var id3 = ViewContext.ParentActionViewContext.RouteData.Values["id3"];
                }
                <div>
                    <div class="@(controller == "Home" && action == "Index" ? "item--active" : "")">
                        @Html.ActionLink("Home", "Index", "Home", null, new { @class = "itemlink" })
                    </div>

                    <div class="@(controller == "Example" && action == "Index" ? "item--active" : "")">
                        @Html.ActionLink("Example", "Index", "Example", null, new { @class = "itemlink" })
                    </div>
                </div>
            </nav>
        </div>
    </div>
</header>
<div class="...">
    @if (!String.IsNullOrEmpty(Model.ExampleName))
    {
        <h2>@("Example - " + Model.ExampleName)</h2>
        @Html.ActionLink(Model.SelectedEntityName, "Index", "Home", null, new { @class = "..." })
        @Html.ActionLink(Model.ExampleName, "SomeEntities", "Example", null, new { @class = "..." })
    }
</div>
<div class="...">
    @if (id3 != null)
    {
        <div class="">
            <div class="@(controller == "Example" && action == "ExampleProperties" ? "tab-active" : "tab-line")">
                @Html.ActionLink("Properties", "ExampleProperties", "Example", null, new { @class = "itemlink" })
            </div>
            <div class="@(controller == "Example" && action == "OtherExampleProperties" ? "tab-active" : "tab-line")">
                @Html.ActionLink("Other Properties", "OtherExampleProperties", "Example", null, new { @class = "itemlink" })
            </div>
            @*...*@
        </div>
    }
    else if (id1 !=  null)
    {
        <div class="">
            <div class="@(controller == "Example" && action == "SomeExamples" ? "tab-active" : "tab-line")">
                @Html.ActionLink("Some Examples", "SomeExamples", "Example", null, new { @class = "itemlink" })
            </div>
            @*...*@
        </div>
    }
</div>

_LayoutMenu Действие Get Get

[HttpGet]
[ChildActionOnly]
public ActionResult LayoutMenu(string selectedEntity, Guid? id1 = null, Guid? id2 = null, Guid? id3 = null)
{
    // my problem: id1, id2, id3 are null after a postback
    var result = new LayoutMenu();
    var entities = _entityHelper.GetEntities();

    if (!String.IsNullOrWhiteSpace(selectedEntity))
    {
        if (entities.Any(entity => entity.GetKey().Equals(selectedEntity)))
        {
            result.SelectedEntityName = entities.First(entity => entity.GetKey().Equals(selectedEntity))?.Name;
        }
        else
        {
            selectedEntity = null;
            result.SelectedEntityName = entities.First().Name;
        }
    }
    else
    {
        result.SelectedEntityName = entities.First().Name;
    }

    result.Entities = new Entities
    {
        EntitiesList = entities,
        SelectedEntity = selectedEntity
    };

    result.ExampleName = id1.HasValue ? _api.GetExample(id1.Value).Name : "";

    if (id2.HasValue && id3.HasValue)
    {
        var data = _api.GetData(id2.Value, id3.Value);
        // result.SomeMoreData = ...
    }

    return PartialView("_LayoutMenu", result);
}

Упрощенный вид обратной передачи

@model namespace.Models.AddData

<div>
    @using (Html.BeginForm())
    {
        @*1st form input fields*@
        <input class="button" type="submit" name="submit" value="Search" />
        @*2nd form input fields in a table*@
        <input class="button" type="submit" name="submit" value="Create" />
    }
</div>

Упрощенный метод обратной передачи

[HttpPost]
public async Task<ActionResult> AddData(Guid id1, AddData model, string submit)
{
    if (!String.IsNullOrEmpty(submit))
    {
        ModelState.Clear();

        if (submit.Equals("Create"))
        {
            // model state checks...

            if (ModelState.IsValid)
            {
                // process and add data.

                // return new statuses
                return View(await CreateModel(id1));
            }

            return View(model);
        }
        else
        {
            // return search
            return View(await CreateModel(id1));
        }
    }
return RedirectToAction(nameof(AddData));
}

1 Ответ

0 голосов
/ 19 марта 2020

Видимо, порядок аргументов в методе действия LayoutMenu важен, поскольку, когда я сначала указывал идентификаторы, а затем selectedEntity и pageTitle (в моей локальной версии), он работал!

Кажется, что пост-метод LayoutMenu (который ниже) вызывался при обратной передаче, и он возвращал метод get с нулевыми значениями для id1, id2 и id3. Как только я добавил эти параметры в метод post и вернул их внизу, все заработало!

[HttpPost]
public ActionResult LayoutMenu(string selectedEntity, string pageTitle, bool? isEntityChange/*, Guid? id1, Guid? id2, Guid? id3*/)
{
    if (isEntityChange.HasValue && isEntityChange.Value)
    {
        if (!String.IsNullOrWhiteSpace(selectedEntity))
        {
            // set selected entity and go to home.
            // ...
            return Redirect(Url.Action("Index", "Home"));
        }
    }

    // this was the faulty code.
    return LayoutMenu(selectedEntity/*,id1, id2, id3*/);
}
...