共用方式為


ASP.NET Web Pages簡介 - 刪除資料庫資料

作者:Tom FitzMacken

本教學課程說明如何刪除個別資料庫專案。 假設您已透過更新 ASP.NET Web Pages 中的資料庫資料來完成系列。

您將學到什麼:

  • 如何從記錄清單中選取個別記錄。
  • 如何從資料庫刪除單一記錄。
  • 如何檢查特定按鈕是否已在表單中按一下。

討論的功能/技術:

  • 協助 WebGrid 程式。
  • SQL Delete 命令。
  • 執行 Database.Execute SQL Delete 命令的方法。

您要建置的內容

在上一個教學課程中,您已瞭解如何更新現有的資料庫記錄。 本教學課程類似,不同之處在于您不會更新記錄,而是將它刪除。 這些程式大致相同,不同之處在于刪除比較簡單,因此本教學課程會很簡短。

在 [ 電影] 頁面中,您將更新 WebGrid 協助程式,使其顯示每個電影旁的 [刪除 ] 連結,以隨附您稍早新增的 編輯 連結。

顯示每個電影的 [刪除] 連結的電影頁面

如同編輯,當您按一下 [刪除] 連結時,它會帶您前往不同的頁面,其中電影資訊已經在表單中:

刪除顯示電影的影片頁面

然後,您可以按一下按鈕永久刪除記錄。

首先,您會將 [刪除] 連結新增至 WebGrid 協助程式。 此連結類似于您在上一個教學課程中新增的 [編輯 ] 連結。

開啟 Movies.cshtml 檔案。

藉由新增資料 WebGrid 行,變更頁面主體中的標記。 以下是修改過的標記:

@grid.GetHtml(
    tableStyle: "grid",
    headerStyle: "head",
    alternatingRowStyle: "alt",
    columns: grid.Columns(
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year"),
grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)
    )
)

新的資料行是這個資料行:

grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)

格線設定的方式, [編輯] 資料行最左邊在方格中, 而 [刪除] 資料行最右邊。 (現在資料行後面 Year 有逗號,如果您沒注意到。) 這些連結資料行的所在位置沒有任何特殊之處,而且您可以輕鬆地將它們放在彼此旁邊。 在此情況下,它們會分開,使其難以混合。

標示為 [編輯] 和 [詳細資料] 連結的電影頁面,顯示它們不在彼此旁邊

新的資料行會顯示連結 (<a> 元素,) 其文字顯示 「Delete」。 連結的目標 (其 href 屬性) 是最終解析為類似此 URL 的程式碼,每個 id 電影的值都不同:

http://localhost:43097/DeleteMovie?id=7

此連結會叫用名為 DeleteMovie 的頁面,並傳遞您所選取電影的識別碼。

本教學課程不會詳細說明如何建構此連結,因為它與上一個教學課程中的編輯連結幾乎相同 (更新ASP.NET Web Pages中的資料庫資料) 。

建立刪除頁面

現在,您可以建立頁面,該頁面將會是方格中 [刪除 ] 連結的目標。

注意

重要 先選取要刪除的記錄,然後使用個別頁面和按鈕來確認程式對於安全性而言非常重要的技術。 如您在先前的教學課程中所閱讀 ,對網站 進行任何變更應該 一律 使用表單來完成,也就是使用 HTTP POST 作業。 如果您只要按一下 (的連結即可變更網站,也就是使用 GET 作業) ,人員就可以對您的網站提出簡單的要求並刪除您的資料。 即使是編制網站索引的搜尋引擎編目程式,也可能不小心遵循下列連結來刪除資料。

當您的應用程式可讓使用者變更記錄時,您仍然必須向使用者呈現記錄以進行編輯。 但您可能想要略過此步驟來刪除記錄。 不過,請勿略過該步驟。 (使用者也可以看到記錄,並確認他們正在刪除其預期的記錄。)

在後續的教學課程集中,您將瞭解如何新增登入功能,讓使用者必須先登入,才能刪除記錄。

建立名為 DeleteMovie.cshtml 的頁面,並以下列標記取代檔案中的內容:

<html>
<head>
  <title>Delete a Movie</title>
</head>
<body>
      <h1>Delete a Movie</h1>
        @Html.ValidationSummary()
      <p><a href="~/Movies">Return to movie listing</a></p>

      <form method="post">
        <fieldset>
        <legend>Movie Information</legend>

        <p><span>Title:</span>
         <span>@title</span></p>

        <p><span>Genre:</span>
         <span>@genre</span></p>

        <p><span>Year:</span>
          <span>@year</span></p>

        <input type="hidden" name="movieid" value="@movieId" />
        <p><input type="submit" name="buttonDelete" value="Delete Movie" /></p>
        </fieldset>
      </form>
    </body>
</html>

此標記就像 EditMovie 頁面,不同之處在于標記不會使用文字方塊 (<input type="text">) ,而是包含 <span> 元素。 這裡沒有任何內容可供編輯。 您只需要顯示電影詳細資料,讓使用者能夠確定他們正在刪除正確的電影。

標記已經包含可讓使用者返回電影清單頁面的連結。

如同在 EditMovie 頁面中,所選電影的識別碼會儲存在隱藏的欄位中。 (它會在第一個位置以查詢字串值的形式傳入頁面。) 有一個 Html.ValidationSummary 呼叫會顯示驗證錯誤。 在此情況下,錯誤可能是未將電影識別碼傳遞至頁面,或影片識別碼無效。 如果有人執行此頁面,而不需要先在 [電影 ] 頁面中選取電影,就可能發生這種情況。

按鈕標題為Delete Movie,其名稱屬性會設定為 buttonDelete 。 屬性 name 將用於程式碼中,以識別提交表單的按鈕。

當您第一次顯示頁面時,您必須將程式碼寫入 1) 閱讀電影詳細資料,而當使用者按一下按鈕時,) 實際刪除電影。

新增程式碼以讀取單一電影

DeleteMovie.cshtml 頁面頂端,新增下列程式碼區塊:

@{
    var title = "";
    var genre = "";
    var year = "";
    var movieId = "";

    if(!IsPost){
        if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()){
            movieId = Request.QueryString["ID"];
            var db = Database.Open("WebPagesMovies");
            var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
            var row = db.QuerySingle(dbCommand, movieId);
            if(row != null) {
                title = row.Title;
                genre = row.Genre;
                year = row.Year;
            }
            else{
                Validation.AddFormError("No movie was found for that ID.");
            }
        }
        else{
            Validation.AddFormError("No movie was found for that ID.");
        }
    }
}

此標記與 EditMovie 頁面中的對應程式碼相同。 它會從查詢字串中取得電影識別碼,並使用識別碼從資料庫讀取記錄。 此程式碼包含驗證測試 (IsInt()row != null) ,以確保傳遞給頁面的電影識別碼有效。

請記住,此程式碼應該只會在第一次執行頁面時執行。 當使用者按一下 [ 刪除電影 ] 按鈕時,您不想從資料庫重新讀取電影記錄。 因此,讀取影片的程式碼是在顯示 if(!IsPost) 的測試內,也就是說, 如果要求不是 (表單提交後作業)

新增程式碼以刪除選取的電影

若要在使用者按一下按鈕時刪除影片,請在區塊的 @ 右大括弧內新增下列程式碼:

if(IsPost && !Request["buttonDelete"].IsEmpty()){
    movieId = Request.Form["movieId"];
    var db = Database.Open("WebPagesMovies");
    var deleteCommand = "DELETE FROM Movies WHERE ID = @0";
    db.Execute(deleteCommand, movieId);
    Response.Redirect("~/Movies");
}

此程式碼類似于用來更新現有記錄但更簡單的程式碼。 程式碼基本上會執行 SQL Delete 語句。

如同在 EditMovie 頁面中,程式碼位於 區塊中 if(IsPost) 。 這次,條件 if() 稍微複雜一點:

if(IsPost && !Request["buttonDelete"].IsEmpty())

此處有兩個條件。 第一個是正在提交頁面,如您之前所見 - if(IsPost)

第二個條件為 !Request["buttonDelete"].IsEmpty() ,表示要求具有名為 buttonDelete 的物件。 當然,這是測試提交表單按鈕的間接方式。 如果表單包含多個提交按鈕,則要求中只會顯示按一下的按鈕名稱。 因此,在邏輯上,如果特定按鈕的名稱出現在要求中,或如程式碼中所述,如果該按鈕不是空的,即為提交表單的按鈕。

&&運算子表示 「and」 (邏輯 AND) 。 因此,整個 if 條件為 ...

此要求是張貼 (不是第一次要求)

AND

buttonDeletebutton 是提交表單的按鈕。

此表單實際上 (,此頁面) 只包含一個按鈕,因此技術上不需要額外的測試 buttonDelete 。 不過,您即將執行將永久移除資料的作業。 因此,只有當使用者明確要求作業時,您才想要確定要執行作業。 例如,假設您稍後展開此頁面,並將其他按鈕新增至該頁面。 即使如此,刪除電影的程式碼只會在按一下按鈕時 buttonDelete 執行。

如同在 EditMovie 頁面中,您會從隱藏欄位取得識別碼,然後執行 SQL 命令。 語句的 Delete 語法為:

DELETE FROM table WHERE ID = value

請務必包含 WHERE 子句和識別碼。 如果您省略 WHERE 子句,將會 刪除資料表中的所有記錄。 如您所見,您會使用預留位置將識別碼值傳遞至 SQL 命令。

測試影片刪除程式

現在您可以測試。 執行 電影 頁面,然後按一下影片旁的 [刪除 ]。 當 [DeleteMovie] 頁面出現時,按一下 [ 刪除電影]。

已醒目提示 [刪除影片] 按鈕的 [刪除影片] 頁面

當您按一下按鈕時,程式碼會刪除電影,並返回電影清單。 您可以在該處搜尋已刪除的影片,並確認其已刪除。

即將推出下一個

下一個教學課程說明如何為網站上的所有頁面提供常見的外觀和版面配置。

@{
    var db = Database.Open("WebPagesMovies") ;
    var selectCommand = "SELECT * FROM Movies";
    var searchTerm = "";

    if(!Request.QueryString["searchGenre"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
        searchTerm = Request.QueryString["searchGenre"];
    }

    if(!Request.QueryString["searchTitle"].IsEmpty() ) {
      selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
      searchTerm = "%" + Request.QueryString["searchTitle"] + "%";
    }

    var selectedData = db.Query(selectCommand, searchTerm);
    var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Movies</title>
      <style type="text/css">
        .grid { margin: 4px; border-collapse: collapse; width: 600px; }
        .grid th, .grid td { border: 1px solid #C0C0C0; padding: 5px; }
        .head { background-color: #E8E8E8; font-weight: bold; color: #FFF; }
        .alt { background-color: #E8E8E8; color: #000; }
      </style>
    </head>
    <body>
      <h1>Movies</h1>
      <form method="get">
        <div>
          <label for="searchGenre">Genre to look for:</label>
          <input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
          <input type="Submit" value="Search Genre" /><br/>
          (Leave blank to list all movies.)<br/>
          </div>

        <div>
          <label for="SearchTitle">Movie title contains the following:</label>
          <input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
          <input type="Submit" value="Search Title" /><br/>
        </div>

      </form>
        <div>
          @grid.GetHtml(
            tableStyle: "grid",
            headerStyle: "head",
            alternatingRowStyle: "alt",
            columns: grid.Columns(
                grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
                grid.Column("Title"),
                grid.Column("Genre"),
                grid.Column("Year"),
                grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)
            )
        )
      </div>
      <p>
        <a href="~/AddMovie">Add a movie</a>
      </p>
    </body>
</html>

DeleteMovie 頁面的完整清單

@{
    var title = "";
    var genre = "";
    var year = "";
    var movieId = "";

    if(!IsPost){
        if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()){
            movieId = Request.QueryString["ID"];
            var db = Database.Open("WebPagesMovies");
            var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
            var row = db.QuerySingle(dbCommand, movieId);
            if(row != null) {
                title = row.Title;
                genre = row.Genre;
                year = row.Year;
            }
            else{
                Validation.AddFormError("No movie was found for that ID.");
            }
        }
        else{
            Validation.AddFormError("No movie was found for that ID.");
        }
    }

    if(IsPost && !Request["buttonDelete"].IsEmpty()){
        movieId = Request.Form["movieId"];
        var db = Database.Open("WebPagesMovies");
        var deleteCommand = "DELETE FROM Movies WHERE ID = @0";
        db.Execute(deleteCommand, movieId);
        Response.Redirect("~/Movies");
    }
}
<html>
<head>
  <title>Delete a Movie</title>
</head>
<body>
      <h1>Delete a Movie</h1>
        @Html.ValidationSummary()
      <p><a href="~/Movies">Return to movie listing</a></p>

      <form method="post">
        <fieldset>
        <legend>Movie Information</legend>

        <p><span>Title:</span>
         <span>@title</span></p>

        <p><span>Genre:</span>
         <span>@genre</span></p>

        <p><span>Year:</span>
          <span>@year</span></p>

        <input type="hidden" name="movieid" value="@movieId" />
        <p><input type="submit" name="buttonDelete" value="Delete Movie" /></p>
        </fieldset>
        <p><a href="~/Movies">Return to movie listing</a></p>
      </form>
    </body>
</html>

其他資源