自動生成された Details および Delete メソッドの確認

作成者: Rick Anderson

Note

Visual Studio の最新バージョンを使用した、このチュートリアルの更新バージョンはこちらにあります。 新しいチュートリアル (このチュートリアルよりも多くの改善がされています) では、ASP.NET Core MVC を使用しています。

このチュートリアルでは、ASP.NET Core MVC のコントローラーとビューについて説明します。 Razor Pages は ASP.NET Core での新しい代替手段であり、Web UI の構築をより簡単かつ生産的にする、ページベースのプログラミング モデルです。 MVC のバージョンの前に、Razor ページのチュートリアルを試すことをお勧めします。 この Razor ページのチュートリアルの特徴は次のとおりです。

  • 使いやすい。
  • 多くの機能をカバーしている。
  • 新しいアプリ開発に推奨されるアプローチです。

チュートリアルのこのパートでは、自動的に生成された Details メソッドと Delete メソッドを確認します。

Details メソッドと Delete メソッドの確認

Movie コントローラーを開いて、Details メソッドを確認します。

[Movies Controller dot c s]\(ムービー コントローラーのドット\) タブを示すスクリーンショット。[作成] ドロップダウン メニューの [詳細] は赤で囲まれています。

public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

このアクション メソッドを作成した MVC スキャフォールディング エンジンにより、メソッドを呼び出した HTTP 要求を示すコメントが追加されます。 この場合は、GET 要求で、Movies コントローラー、Details メソッド、ID 値という 3 つの URL セグメントが含まれます。

Code First は、Find メソッドによるデータの検索を容易にします。 このメソッドに組み込まれている重要なセキュリティ機能は、Find メソッドがムービーだと認識したことを、コードがそれに対して何かを実行する前にコードで検証することです。 たとえば、ハッカーは、リンクによって作成される URL を http://localhost:xxxx/Movies/Details/1 から http://localhost:xxxx/Movies/Details/12345 など (または、実際のムービーを表していないその他の値) に変更することで、サイトでエラーを発生させる可能性があります。 null ムービーをチェックしなかった場合、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 メソッドは指定されたムービーを削除するのではなく、削除を送信 (HttpPost) できるムービーのビューを返すことに注意してください。 GET 要求の応答で削除操作を実行すると (さらに言えば、編集操作、作成操作、データを変更するその他のあらゆる操作を実行すると)、セキュリティに穴が空きます。

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

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

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

共通言語ランタイム (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");
}

まとめ

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

[M V C Movie Search Index]\(M V C ムービー検索インデックス\) ページを示すスクリーンショット。

次のステップ

Web アプリケーションを構築してテストしたら、次の手順は、他のユーザーがそのアプリケーションをインターネット経由で使用できるようにすることです。 そのためには、Web ホスティング プロバイダーにデプロイする必要があります。 Microsoft は、無料の Azure 試用版アカウント内で、最大 10 の Web サイトに対して無料の Web ホスティングを提供しています。 次は、メンバーシップ、OAuth、SQL Database を備えた安全な ASP.NET MVC アプリを Azure にデプロイするのチュートリアルをお勧めします。 優れたチュートリアルは、Tom Dykstra の中級レベルの ASP.NET MVC アプリケーション用の Entity Framework データ モデルの作成です。 StackoverflowASP.NET MVC フォーラムは、質問するのに最適な場所です。 Twitter で筆者をフォローして、最新のチュートリアルの更新情報を入手してください。

ご意見をお待ちしております。

- Rick Anderson twitter: @RickAndMSFT
- Scott Hanselman twitter: @shanselman