2016-07-15 97 views
0

我在视图中定义的操作链接ActionLink的不是呼叫控制器

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

我在这里丢失的任何东西

Full Vi EW代码

@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") 
      } 
+2

卸下'[HttpPost]'属性(一个链路发出GET,而不是一个POST)。因为你的方法正在改变数据 - 它应该是一个POST,并且在视图中使用一个表单。你也可以删除'if(ModelState.IsValid){' - 你不绑定到模型,所以它总是'真' –

+0

删除现有的表单,并为每个项目,使用@using(Html.BeginForm(“MarkComplete” ,“yourController”,new {id = item.ID})){@ Html.AntiForgeryToken()}'也考虑使用ajax,以便用户可以继续 –

回答

2

你的动作标有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") 
} 
+0

我有'HTTPPost'属性,因为这个方法会更新数据 – Darkestlyrics

+0

@Darkkelyrics好的,那么你需要一个表单并使用'[ValidateAntiForgeryToken]',否则就会出现 – kamilk

+0

尝试了你的方法,点击按钮,重置视图(没有任务),但它看起来并不像它在我的控制器中击中MarkComplete方法(断点没有被击中) – Darkestlyrics