檢查 ASP.NET Core 應用的 Details 和 Delete 方法

2019-04-17 08:57 更新

打開電影控制器,并檢查 Details 方法:

C#

// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    if (movie == null)
    {
        return NotFound();
    }

    return View(movie);
}

創(chuàng)建此操作方法的 MVC 基架引擎添加顯示調用方法的 HTTP 請求的注釋。 在此情況下,它是包含三個 URL 段的 GET 請求,這三個段為 Movies 控制器、Details 方法和 id 值。 回顧這些在 Startup.cs 中定義的段。

C#

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

EF 可以使用 FirstOrDefaultAsync 方法輕松搜索數(shù)據(jù)。 該方法中內置的一個重要安全功能是,代碼會先驗證搜索方法已經找到電影,然后再執(zhí)行操作。 例如,一個黑客可能通過將鏈接創(chuàng)建的 URL 從 http://localhost:xxxx/Movies/Details/1 更改為類似 http://localhost:xxxx/Movies/Details/12345 的值(或者不代表任何實際電影的其他值)將錯誤引入站點。 如果未檢查是否有空電影,則應用可能引發(fā)異常。

檢查 Delete 和 DeleteConfirmed 方法。

C#

// GET: Movies/Delete/5
public async Task<IActionResult> Delete(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    if (movie == null)
    {
        return NotFound();
    }

    return View(movie);
}

// POST: Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
    var movie = await _context.Movie.FindAsync(id);
    _context.Movie.Remove(movie);
    await _context.SaveChangesAsync();
    return RedirectToAction(nameof(Index));
}

請注意,HTTP GET Delete 方法不刪除指定的電影,而是返回可在其中提交 (HttpPost) 刪除的電影視圖。 執(zhí)行刪除操作以響應 GET 請求(或者說,執(zhí)行編輯操作、創(chuàng)建操作或更改數(shù)據(jù)的任何其他操作)會打開安全漏洞。

刪除數(shù)據(jù)的 [HttpPost] 方法命名為 DeleteConfirmed,以便為 HTTP POST 方法提供一個唯一的簽名或名稱。 下面顯示了兩個方法簽名:

C#

// GET: Movies/Delete/5
public async Task<IActionResult> Delete(int? id)
{

C#

// POST: Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{

公共語言運行時 (CLR) 需要重載方法擁有唯一的參數(shù)簽名(相同的方法名稱但不同的參數(shù)列表)。 但是,這里需要兩個 Delete 方法 -- 一個用于 GET,另一個用于 POST -- 這兩個方法擁有相同的參數(shù)簽名。 (它們都需要接受單個整數(shù)作為參數(shù)。)

可通過兩種方法解決此問題,一種是為方法提供不同的名稱。 這正是前面的示例中的基架機制進行的操作。 但是,這會造成一個小問題:ASP.NET 按名稱將 URL 段映射到操作方法,如果重命名方法,則路由通常無法找到該方法。 該示例中也提供了解決方案,即向 DeleteConfirmed 方法添加 ActionName("Delete") 屬性。 該屬性對路由系統(tǒng)執(zhí)行映射,以便包括 POST 請求的 /Delete/ 的 URL可找到 DeleteConfirmed 方法。

對于名稱和簽名相同的方法,另一個常用解決方法是手動更改 POST 方法的簽名以包括額外(未使用)的參數(shù)。 這正是前面的文章中添加 notUsed 參數(shù)時進行的操作。 這里為了 [HttpPost] Delete方法可以執(zhí)行同樣的操作:

C#

// POST: Movies/Delete/6
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(int id, bool notUsed)


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號