次の方法で共有


Details メソッドと Delete メソッドの改善 (C#)

作成者: Rick Anderson

Note

ASP.NET MVC 5 と Visual Studio 2013 を使用するこのチュートリアルの更新版は、こちらで入手できます。 より安全で、より簡単に操作でき、より多くの機能を備えています。

このチュートリアルでは、Microsoft Visual Web Developer 2010 Express Service Pack 1 (Microsoft Visual Studio の無料版) を使用した ASP.NET MVC Web アプリケーション構築の基本事項を説明します。 開始する前に、以下に示す前提条件がインストールされていることを確認してください。 次のリンクをクリックすると、これらをすべてインストールできます: Web Platform Installer。 また、次のリンクを使用して前提条件となるソフトウェアを個別にインストールすることもできます。

Visual Web Developer 2010 ではなく Visual Studio 2010 を使用する場合は、Visual Studio 2010 の前提条件のリンクをクリックして、前提条件をインストールします。

このトピックに関連する、Visual Web Developer プロジェクトと C# ソース コードを使用できます。 C# バージョンをダウンロードします。 Visual Basic を使用する場合は、このチュートリアルの Visual Basic バージョンに切り替えてください。

このチュートリアルのパートでは、自動的に生成された Details メソッドと Delete メソッドにいくつかの改善を加えます。 これらの変更は必須ではありませんが、少しのコードを使用するだけで、アプリケーションを簡単に強化できます。

Details メソッドと Delete メソッドの改善

Movie コントローラーをスキャフォールディングした際に、ASP.NET MVC によってうまく動作するコードが生成されましたが、小さな変更を加えるだけでそれをより堅牢なものにできます。

Movie コントローラーを開き、Details メソッドを修正して、ムービーが見つからないときに HttpNotFound を返すようにします。 また、渡される ID の既定値を設定するように Details メソッドを修正する必要もあります。 (このチュートリアルのパート 6 では、Edit メソッドに同じような変更を行いました。)ただし、HttpNotFound メソッドは ViewResult オブジェクトを返さないため、Details メソッドの戻り値の型を ViewResult から ActionResult に変更する必要があります。 次の例は、修正した Details メソッドを示しています。

public ActionResult Details(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

Code First は、Find メソッドによるデータの検索を容易にします。 このメソッドには重要なセキュリティ機能が組み込まれています。Find メソッドがムービーを見つけたことをコードが確認するまでは、何も処理を行いません。 たとえば、ハッカーは、リンクによって作成される URL を http://localhost:xxxx/Movies/Details/1 から http://localhost:xxxx/Movies/Details/12345 など (または、実際のムービーを表していないその他の値) に変更することで、サイトでエラーを発生させる可能性があります。 null 値のムービーをチェックしない場合、データベース エラーが発生する可能性があります。

同様に、Delete メソッドと DeleteConfirmed メソッドに変更を加えて、ID パラメーターのデフォルト値を指定して、ムービーが見つからなかったときには HttpNotFound を返すようにします。 Movie コントローラーの更新された Delete メソッドを次に示します。

// GET: /Movies/Delete/5

public ActionResult Delete(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

//
// POST: /Movies/Delete/5

[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    db.Movies.Remove(movie);
    db.SaveChanges();
    return RedirectToAction("Index");
}

Delete メソッドはデータを削除しません。 GET 要求の応答で削除操作を実行すると (さらに言えば、編集操作、作成操作、データを変更するその他のあらゆる操作を実行すると)、セキュリティに穴が空きます。

データを削除する HttpPost メソッドの名前は「DeleteConfirmed」になり、HTTP POST メソッドに一意のシグネチャまたは名前が与えられます。 2 つのメソッド シグネチャは下の画像のようになります。

// GET: /Movies/Delete/5
public ActionResult Delete(int id = 0)

//
// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id = 0)

共通言語ランタイム (CLR) では、オーバーロードしたメソッドに一意のシグネチャ (同じ名前、異なるパラメーターのリスト) が必要です。 ただし、ここでは同じシグネチャを要求する 2 つの Delete メソッド (GET 用と POST 用) が必要になります。 (いずれも、1 つの整数をパラメーターとして受け取る必要があります。)

これらを区別するために、いくつかのことを行えます。 1 つは、メソッドに異なる名前を付けることです。 以前の例では、これを行いました。 しかし、これは小さな問題を引き起こします。ASP.NET が URL のセグメントをアクション メソッドに名前でマッピングします。メソッドの名前を変更すると、通常、ルーティングでそのメソッドが見つからなくなります。 この解決策はこの例で確認できます。ActionName("Delete") 属性を DeleteConfirmed メソッドに追加しています。 これは実質的に、ルーティング システムに対してマッピングを行って、POST 要求の /Delete/ を含む URL が DeleteConfirmed を見つけられるようにすることです。

同じ名前とシグネチャを持つメソッドの問題を回避するもう 1 つの方法は、POST メソッドのシグネチャを人為的に変更して、未使用のパラメーターを含めることである。 たとえば、一部の開発者は 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");
}

まとめ

これで、SQL Server Compact データベースにデータを格納する、ASP.NET MVC アプリケーションが完成しました。 ムービーの作成、読み取り、更新、削除、検索を行うことができます。

M V C Movie アプリの [検索インデックス] ページを示すスクリーンショット。このページには、4 つの映画の一覧が表示されます。

この基本的なチュートリアルでは、コントローラーを作成し、それらをビューに関連付け、ハードコーディングされたデータを渡しました。 そして、データ モデルを作成して設計しました。 Entity Framework の Code First がデータ モデルからデータベースをすぐに作成し、ASP.NET MVC のスキャフォールディング システムが、基本的な CRUD 操作のためのアクション メソッドとビューを自動で作成しました。 その後、ユーザーがデータベースを検索するための検索フォームを追加しました。 新しい列のデータを含むようにデータベースを変更し、この新しいデータを作成して表示するように 2 つのページを更新しました。 DataAnnotations 名前空間の属性を使用してデータ モデルにマークを付けることで、検証を追加しました。 追加した検証は、クライアントとサーバーで実行されます。

アプリケーションをデプロイする場合は、まずローカルの IIS 7 サーバーでアプリケーションをテストすることをお勧めします。 この Web Platform Installer リンクを使用して、ASP.NET アプリケーション用の IIS 設定を有効にできます。 以下のデプロイに関するリンクを参照してください。

次に、中級レベルのチュートリアル「ASP.NET MVC アプリケーション用の Entity Framework データ モデルの作成」と「MVC Music Store」に進み、MSDN の ASP.NET の記事を探し、https://asp.net/mvc で多数のビデオと資料を確認して、ASP.NET MVC についてさらに詳しく学習することをお勧めします! 質問がある場合は、ASP.NET MVC フォーラムにアクセスしてください。

お楽しみに!

— Scott Hanselman (http://hanselman.com@shanselman (Twitter)) および Rick Anderson blogs.msdn.com/rickAndy