不允许子操作执行重定向操作部分视图

Child Actions are not allowed to perform redirect actions Partial Views

在我的主视图中,我有 4 个局部视图。两个是表格。其他是创建表单。

部分视图 Table 1

@model IEnumerable<ProjectName.Models.code_AutoMake>

<h3>Auto Make List</h3>
<table id="Auto-Make-Table" class="table table-bordered table-striped">
    <thead>
        <tr>
            <th class="col-md-5">
                @Html.DisplayNameFor(model => model.AutoMake)
            </th>
            <th class="col-md-5">
                @Html.DisplayNameFor(model => model.Active)
            </th>
            <th></th>
        </tr>
    </thead>

    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.AutoMake)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Active)
                </td>
                @if (!item.Active)
                {
                    <td>
                        @Html.ActionLink("Edit", "Edit", new { id = item.MakeID }) |
                        <a href="#" class="text-info js-automake-activate" data-automake-id="@item.MakeID" data-automake-name="@item.AutoMake">Activate</a>
                    </td>
                }
                else
                {
                    <td>
                        @Html.ActionLink("Edit", "Edit", new { id = item.MakeID }) |
                        <a href="#" class="text-danger js-automake-delete" data-automake-id="@item.MakeID" data-automake-name="@item.AutoMake">Deactivate</a>
                    </td>
                }

            </tr>
        }
    </tbody>
</table>

部分视图 Table 2

@model IEnumerable<ProjectName.Models.code_Funding>

<h3>Funding List</h3>
<table class="table table table-bordered table-striped">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Funding)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Active)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Funding)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Active)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", "code_Funding",new { id=item.FundID }, null) |
        </td>
    </tr>
}

</table>

部分视图 1 创建

@model ProjectName.Models.code_AutoMake

@using (Html.BeginForm("Create", "code_AutoMake", FormMethod.Post))
{
    @Html.AntiForgeryToken()
    <h3>Add Auto Make</h3>
    <div class="form-horizontal">

        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="row">
            <div class="col-sm-12 col-md-3">
                @Html.Label("Auto Make")
                @Html.EditorFor(model => model.AutoMake, new {htmlAttributes = new {@class = "form-control"}})
            </div>
            <div class="col-sm-12 col-md-3">
                @Html.Label("Active")
                    <div class="checkbox">
                        @Html.EditorFor(model => model.Active)
                    </div>
            </div>
        </div>

        <div class="form-group">
            <div class="col-sm-12 col-md-3">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

部分视图 2 创建

@model ProjectName.Models.code_Funding

@using (Html.BeginForm("Create", "code_Funding", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    <h3>Add Funding</h3>
    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="row">
            <div class="col-sm-12 col-md-3">
                @Html.Label("Funding")
                @Html.EditorFor(model => model.Funding, new {htmlAttributes = new {@class = "form-control"}})
            </div>
            <div class="col-sm-12 col-md-3">
                @Html.Label("Active")
                <div class="checkbox">
                    @Html.EditorFor(model => model.Active)
                </div>
            </div>
        </div>

        <div class="form-group">
            <div class="col-sm-12 col-md-3">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

主视图

<div id="AutoMake" class="tab-pane fade active in">
    <div id="AutoMake-Index">@{Html.RenderAction("Index", "code_AutoMake");}</div>
    <hr/>
    @{Html.RenderAction("Create", "code_AutoMake");}
</div>
@*Funding*@
<div id="Funding" class="tab-pane fade">
    @{Html.RenderAction("Index", "code_Funding");}
    <hr/>
    @{Html.RenderAction("Create", "code_Funding");}
</div>

现在是这样的场景..当我想创建一个新的 autoMake..我填写表格并点击提交..一切顺利..直到我回到主视图.. 特别是这一行:

@{Html.RenderAction("Create", "code_Funding");}

我收到一个运行时错误:

Child Actions are not allowed to perform redirect actions

我已经调试了.. 出于某种原因.. code_FundingHttpPost Create 操作正在被触发.. 即使我没有填写 [=66= 的创建表单]..这怎么可能?

这是我为 code_autoMake 和 code_funding 创建的方法:

code_Funding

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "FundID,Funding,Active")] code_Funding code_Funding)
    {
        try
        {
            if (ModelState.IsValid)
            {
                db.code_Funding.Add(code_Funding);
                db.SaveChanges();
                return RedirectToAction("EditDDL", "tblNewAutos");
            }
        }
        catch (DbEntityValidationException ex)
        {
            foreach (var entityValidationErrors in ex.EntityValidationErrors)
            {
                foreach (var validationError in entityValidationErrors.ValidationErrors)
                {
                    Response.Write("Property: " + validationError.PropertyName + " Error: " + validationError.ErrorMessage);
                }
            }
        }
        return RedirectToAction("EditDDL", "tblNewAutos");
    }

code_autoMake

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "MakeID,AutoMake,Active")] code_AutoMake code_AutoMake)
    {

            if (ModelState.IsValid)
            {
                db.code_AutoMake.Add(code_AutoMake);
                db.SaveChanges();
                return PartialView("~/Views/PartialViews/_AutoMakeCreate.cshtml");
            }


        return RedirectToAction("EditDDL", "tblNewAutos");
    }

为什么当我尝试创建一个新的 automake.. 两个 HttpPost Create 方法都被命中?

感谢任何帮助。

嗯,问题如下。在您的主视图中,您有以下代码:

...
@{Html.RenderAction("Create", "code_AutoMake");}
...

这会触发 Create 操作,如果 ModelState.IsValid == false:

,则该操作以以下代码行结束
return RedirectToAction("EditDDL", "tblNewAutos");

这显然是个坏主意。为什么?您已经在渲染父视图。子操作起初可能有点混乱,因为它们不是真正的操作 - 没有 client/server 通信。你还在服务器端。因此子操作中不允许重定向。

解决方案

首先,我不太确定你想要实现什么,所以我的解决方案推荐可能有点偏差,但让我们看看。

选项 1

您可能想要使用两种不同的操作。一个在提交表单时调用,另一个在您的主视图中调用。后者不应进行重定向 - 相反,如果这确实是您需要的,它应该根据 ModelState.IsValid 明智地选择要呈现的视图。

选项 2

有一种 hack 方法可以让您从子操作进行重定向。不是进行重定向,而是仅存储有关所需重定向的信息,例如 HttpContext.Items 集合中的信息。然后,实现一个 ActionFilter 并在其 OnResultExecuted 事件中检查重定向请求是否设置为 HttpContext.Items。如果是这样,请进行重定向。 ActionFilter 应该应用于父操作,而不是子操作。

@{Html.RenderAction("Create", "code_Funding");} 

在此 RenderAction 方法中调用 GET 请求,但是您的控制器只编写了 post 方法。然后你写

[ChildActionOnly]  
public ActionResult Create(string parm)
{
 reurn view()
}

并使用 [ChildActionOnly] 此属性允许通过视图中的代码进行限制访问。

查看并回复我..