檢查 ASP.NET Core 應(yīng)用的 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 基架引擎添加顯示調(diào)用方法的 HTTP 請(qǐng)求的注釋。 在此情況下,它是包含三個(gè) URL 段的 GET 請(qǐng)求,這三個(gè)段為 Movies 控制器、Details 方法和 id 值。 回顧這些在 Startup.cs 中定義的段。

C#

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

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

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

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

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)
{

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

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

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

C#

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


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)