[ASP.NET MVC] 檢視系統自動產生的Details與Delete方法
檢視Details與Delete方法
開啟MoviesController,檢視Details方法:
MVC建立的Action方法上方有一行註解,顯示是哪一種HTTP要求呼叫這個方法。GET要求的URL分為三段,Movies Controller/Details方法/ID。
Code First可以使用Find方法搜尋資料。Find方法中內建了驗證的安全功能,可以在搜尋電影後與進行操作前進行資料的驗證。
例如,使用者輸入網址 //localhost:xxxx/Movies/Details/12345 (Details後的參數不是真正的電影ID),若沒有檢查查詢後的電影是否為Null,便會導致資料庫錯誤。
檢視Delete與DeleteConfirmed的方法:
// GET: Movies/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
// POST: Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Movie movie = db.Movies.Find(id);
db.Movies.Remove(movie);
db.SaveChanges();
return RedirectToAction("Index");
}
看到HTTP GET的Delete方法沒有刪除指定的電影,而是回傳一個電影的View來提交(HTTP POST)刪除。執行一個刪除作業來應對GET要求(或是說執行編輯、新增、或其他會變更資料作業)會造成資安漏洞。
用來刪除資料的HttpPost方法,名字叫做DeleteConfirmed。為了給予HTTP POST唯一的屬名,Delete與DeleteConfirmed這兩個方法的參數與名稱如下:
// GET: Movies/Delete/5
public ActionResult Delete(int? id)
// POST: Movies/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
多載方法有一個獨特的參數簽名(相同名稱但不同的參數項目)。然而,這裡你需要兩個Delete方法,一個是GET,一個是POST,而兩個都有相同的參數(ID)。
為了區分這兩個方法,你可以做兩件事情。一是將這兩個方法取不同的名稱。但是ASP.NET會依照URL的段落尋找Action方法的名稱,要是將方法重新命名,那麼正常的路徑就不能找到要對應的方法。
為了解決這個問題,可以像上方的程式碼,在DeleteConfirmed方法加入ActionName("Delete")屬性。這樣便能讓URL包含/Delete/的POST要求找到DeleteConfirmed方法。
另一個常見的方法是在POST方法多加一個不會使用到的參數。例如,FormCollection:
public ActionResult Delete(FormCollection fcNotUsed, int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
db.Movies.Remove(movie);
db.SaveChanges();
return RedirectToAction("Index");
}