2015-12-02 60 views
1

我仍然處在MVC的學習過程中,很長一段時間來自Web窗體。我試圖理解的一件事是將按鈕/輸入與ActionResult關聯的適當方式。澄清接線按鈕到ActionResult

我一直用作示例的項目之一是Contoso大學。在該項目中,他們有一個CourseController,在Course/Edit.cshtml頁面中他們使用一個不指定控制器或操作方法的表單。所以我不清楚表單如何知道它需要去哪裏,因爲表單或按鈕都不指向控制器/操作方法。是因爲該頁面被命名爲Edit並且ActionResult也被命名爲Edit?

這是Contoso .cshtml和控制器中的ActionResult。

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

    <div class="form-horizontal"> 
     <h4>Course</h4> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     @Html.HiddenFor(model => model.CourseID) 

     <div class="form-group"> 
      @Html.LabelFor(model => model.CourseID, new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.DisplayFor(model => model.CourseID) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Credits, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Credits, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Credits, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      <label class="control-label col-md-2" for="DepartmentID">Department</label> 
      <div class="col-md-10"> 
       @Html.DropDownList("DepartmentID", null, htmlAttributes: new { @class = "form-control" }) 
       @Html.ValidationMessageFor(model => model.DepartmentID, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Save" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 

[HttpPost, ActionName("Edit")] 
     [ValidateAntiForgeryToken] 
     public ActionResult EditPost(int? id) 
     { 
      if (id == null) 
      { 
       return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
      } 
      var courseToUpdate = db.Courses.Find(id); 
      if (TryUpdateModel(courseToUpdate, "", 
       new string[] { "Title", "Credits", "DepartmentID" })) 
      { 
       try 
       { 
        db.SaveChanges(); 

        return RedirectToAction("Index"); 
       } 
       catch (RetryLimitExceededException /* dex */) 
       { 
        //Log the error (uncomment dex variable name and add a line here to write a log. 
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); 
       } 
      } 
      PopulateDepartmentsDropDownList(courseToUpdate.DepartmentID); 
      return View(courseToUpdate); 
     } 

而且我已經與一些搜索找到另一件事是開發者調用形式控制器/操作方法,以及直接通過按鈕或輸入指向控制器/操作方法。

在這裏,他們在窗體中添加它。

@using (Html.BeginForm("SignUp", "Account", FormMethod.Post)) 
{ 
    <!-- form goes here --> 

    <input type="submit" value="Sign Up" /> 
} 

這裏它直接在按鈕中。

<button type="button" onclick="location.href='@Url.Action("MyAction", "MyController")'" > 

使用這些方法有什麼優點/缺點嗎?對我而言,如果將控件/方法放在表單聲明中或直接放在按鈕上,這似乎更加清晰。

回答

2

這些簡單地不同overloadsBeginForm方法。

@using (Html.BeginForm()) {}將呈現表單標籤,其中action屬性值設置爲當前頁面。這意味着,如果你是渲染創建頁面(郵政/創建),此重載將呈現以下HTML

<form action="/Post/Create" method="post"></form> 

默認情況下,BeginForm將呈現設定爲「POST」方法值的形式標記。

第二個重載可以讓你明確指定目標的行動值

所以,如果你有內部下面的代碼,您創建Razor視圖(Post/Create

@using (Html.BeginForm("Edit", "Post")) 
{ 
    <input type="text" name="postName" /> 
} 

,這會使得

<form action="/Post/Edit" method="post"> 
    <input type="text" name="postName" /> 
</form> 

您需要確保您有用[HttpPost]屬性修飾的操作方法來處理控制器中的表單發佈

[HttpPost] 
public ActionResult Edit(string postName) 
{ 
//to do : Do something useful 
    return View(); 
} 

我們有另一個overload它允許我們明確指定表單發佈方法。默認值是POST,您可以使用此重載將其改爲GET(但99%的時候,你將使用POST類型。)

@using (Html.BeginForm("Edit","Post",FormMethod.Get)) 
{  
} 

你可以看到所有可用的重載here。嘗試不同的,看看這些產生的html輸出(你可以在頁面上做「查看源代碼」)。

最後,當您單擊表單內的提交按鈕時,表單將被提交到目標操作。

這意味着,你不需要(也不應該這樣做在正常使用情況下)

<button type="button" onclick="location.href='@Url.Action("MyAction", "MyController")'" > 

但這足以

​​
+0

感謝您的解釋。這絕對有幫助。因此,基本上,因爲Contoso示例沒有專門向表單添加任何內容,所以它將根據.cshtml的名稱提取方法名稱,並且因爲它發現控制器文件夾中的View文件,它將假定作爲要使用的控制器。否則,如果我想從用於顯示錶單的控制器/視圖中獲取不同的控制器或方法名稱,則必須在Html.BeginForm聲明中指定該名稱。 – Caverman

0

每一個方法都有一定的優勢 1)的ActionResult名將顯示在網址中,也可以直接獲取該動作的結果abd其同步調用或其直接服務器調用 2)@ url.action我們用於相對路徑某些時候url無法識別第二級用於處理我們使用的那些問題@ url.a爲更好的理解它檢查絕對和相對路徑 3)你可以使ajax調用異步調用來獲得更好的性能。希望它對你有所幫助。