【问题标题】:ActionLink not calling ControllerActionLink 没有调用控制器
【发布时间】:2016-07-15 20:59:08
【问题描述】:

我的视图中定义了一个操作链接

@Html.ActionLink("Mark as Completed", "MarkComplete", new { id = item.ID })

但是这不会调用我的控制器中的方法,而是它产生以下链接的链接

http://localhost:52069/Users/MarkComplete/3

    [HttpPost]
    public ActionResult MarkComplete(int? id) {
        if (id == null) {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
        Task task = db.Tasks.Find(id);
        if (task == null) {
            return HttpNotFound();
            }
        if (ModelState.IsValid) {
            task.Completed = 1;
            db.Entry(task).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
            }
        return View(task);
        }

我在这里缺少的任何东西

完整查看代码

@model IEnumerable<Base.Models.Task> @{
    ViewBag.Title = "UserTasks"; }

<h2>User</h2>


@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()

        <h4>Task for User</h4>
        <table class="table">
            <tr>  
                <th>
                    Name
                </th>
                <th>
                    Details
                </th>
                <th>
                    Start Date
                </th>
                <th>
                    Due Date
                </th>
             </tr>
                    @foreach (var item in Model) {
                <tr>
                    <td>@item.Name </td>
                    <td>@item.Details</td>
                    <td>@item.StartDate.ToShortDateString()</td>
                    <td>@item.EndDate.ToShortDateString()</td>
                    <td>
                        @Html.ActionLink("Mark as Completed", "MarkComplete", new { id = item.ID })
                    </td>
                </tr>
                        }
                </table>
    }
            <div>
                @Html.ActionLink("Back to List", "Index")
            </div>

            @section Scripts {
                @Scripts.Render("~/bundles/jqueryval")
            }

【问题讨论】:

  • 删除 [HttpPost] 属性(链接生成 GET,而不是 POST)。 Vut 因为您的方法正在更改数据 - 它应该是一个 POST,并且在视图中使用一个表单。你也可以删除if (ModelState.IsValid) { - 你没有绑定到模型,所以它总是true
  • 删除现有表单,并为每个项目使用@using (Html.BeginForm("MarkComplete", "yourController", new { id = item.ID })) { @Html.AntiForgeryToken() &lt;input type="submit value="Mark as Completed" /&gt; }。还可以考虑使用 ajax,这样用户就可以留在页面上并继续“标记为已完成”其他项目。

标签: c# asp.net-mvc razor


【解决方案1】:

您的操作用HttpPost 属性标记,而ActionLink 会产生GET 请求。更准确地说,ActionLink 呈现一个锚标记,单击该标记时会向服务器发送一个GET 请求。

是否有任何特殊原因使该操作被标记为HttpPost 属性?您可能想要删除该属性或将其替换为 HttpGet 属性。

如果出于某些原因要求该操作仅侦听 POST 请求,那么您可以使用一个带有链接样式的单个按钮的表单,而不是使用 ActionLink

@using(Html.BeginForm("MarkComplete", "Users")) {
    <input type="hidden" name="id" value="@item.ID">
    <input type="submit" value="Mark as Completed" />
}

但是,您已经将整个表格包裹在表单中,是的,表单不能嵌套,因此您需要更大幅度地更改视图。

所以整个视图可能如下所示:

@model IEnumerable<Base.Models.Task>
@{ ViewBag.Title = "UserTasks"; }

<h2>User</h2>

<h4>Task for User</h4>
<table class="table">
    <tr>  
        <th>
            Name
        </th>
        <th>
             Details
        </th>
        <th>
            Start Date
        </th>
        <th>
            Due Date
        </th>
    </tr>
    @foreach (var item in Model) {
        <tr>
            <td>@item.Name </td>
            <td>@item.Details</td>
            <td>@item.StartDate.ToShortDateString()</td>
            <td>@item.EndDate.ToShortDateString()</td>
            <td>
                @using(Html.BeginForm("MarkComplete", "Users")) {
                    @Html.AntiForgeryToken()
                    <input type="hidden" name="id" value="@item.ID">
                    <input type="submit" value="Mark as Completed" />
                }
            </td>
        </tr>
    }
</table>

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

【讨论】:

  • 我有 HTTPPost 属性,因为此方法将更新数据
  • @Darkestlyrics 好。然后你需要一个表格并使用[ValidateAntiForgeryToken]。否则,将其作为 POST 没有任何好处,因为您的电话不会有任何正文。
  • 试过你的方法,点击那里的按钮重置视图(没有任务)但是它似乎没有在我的控制器中达到 MarkComplete 方法(断点没有被击中)
  • 所以我发现出了什么问题,它指向不同的控制器,但这个答案让我陷入了这种思维方式。
  • @Darkestlyrics,对不起,我的代码中出现了愚蠢的错误。请在 BeginForm 方法中的操作名称之后提供控制器 - 在您的情况下是“UsersController”吗?所以它可能看起来像:Html.BeginForm("MarkComplete", "Users")
【解决方案2】:

将 ActionLink 替换为

<input type="submit" value="Mark as Completed"> 

所以它会做一个 POST。

将表单的操作设置为 ActionLink 指向的位置。

https://weblogs.asp.net/scottgu/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios

【讨论】:

    猜你喜欢
    • 2015-01-04
    • 2012-08-11
    • 1970-01-01
    • 2015-05-05
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    相关资源
    最近更新 更多