次の方法で共有


[翻訳]Web 開発入門:Part 6 新規追加画面の作成 (20110216)

今回は Part 6 新規追加画面の作成の翻訳原稿です。
データベースの参照だけではなく、新規のレコードをデータベースに追加する処理を紹介します。

元ネタはこちら
Web Development 101- Part 6, Creating an Add Data page

今回の翻訳のメニューはこちらから
WebMatrix を使ったWeb開発入門の翻訳始めます!(20110204)


Web 開発入門:Part 6 新規追加画面の作成

これまで、WebMatrix を使って Web サイトを作成する方法、スタイルやレイアウトを使用してページをシンプルにすることで管理を容易にし、さらに表示速度を上げる方法を学んできました。また、データベースのデータを利用して動的 Web ページを作成しました。このパートではデータベースにデータを追加するページを作成する方法を学びます。

新規追加のためのページへのリンクを作成する

WebMatrix の [ファイル] 作業領域で “AddMovie.cshtml” という新しいページを作成します。

WebMatrix が作成する初期のコードを削除して、次のコードを記述してください。

 <h1>Add a New Movie to the database</h1>

続いて “dataMovies.cshtml” ファイルを開いてください。次のようなコードになっているはずです。

 @{
    var db= Database.Open("Movies");
    var sqlQ = "SELECT * FROM Favorites";
    var data = db.Query(sqlQ);   
}
 
<div id="movieslist">
  <ol>
    @foreach(var row in data){
      <li><a href="#">@row.Name, @row.Genre, @row.ReleaseYear</a></li>
    }
  </ol>
</div>

</div> タグの前に次のような HTML を追加します。以前のパートで扱った他のページにリンクを張るアンカー (ハイパー リンク) を思い出してください。

 <a href="AddMovie.cshtml">Add a new movie</a>

サイトを実行してブラウザでページを見てみましょう。次のように表示されるはずです。

01

“Add a new movie” のリンクをクリックすると先ほど作成した下記のようなページが表示されます。

02

現時点ではほとんど意味のないページですが、これからここに様々なものを足していきます。

その前に、ちょっとした復習をしてみましょう。“Add a New Movie to the Database” の文字列がほかの文字列と異なるスタイルをしているのに気付いたでしょうか?この文字列は <h1> ですが、ヘッダーの <h1> の文字列とはスタイルが異なります。これはなぜだかわかりますか?(ヒント:ヘッダーの h1 は <header> タグの子要素として認識されていますが、この文字列は違います。CSSファイルにどのように何を足すと同じになりますか?)

映画を追加するフォームを作成する

一般的に HTTP を使ってブラウザからサーバーに要求をする場合は、GET というメソッドを使います。名前から推測できる通り、これは情報をサーバーから取り寄せるためのメソッドです。今までこれを意識したことはないと思います。なぜなら GET を使う場合はブラウザがページを要求する際に暗黙的に使われているからです。また、HTTP プロトコルはGETだけではなく、情報をサーバーに送るための POST というメソッドもあります。

今まで見てきたとおり動的なアプリケーションを使うことは有益なことですが、次のステップとしてサーバーにデータを送信してサーバー側で何らかの処理をし、その結果をブラウザに戻すという複雑な部分を理解しなければなりません。

今までに送信ボタンを押して入力した情報をサーバーに送るという体験をしたことがあると思います。それらのアプリケーションは HTML のフォームを使っています。送信ボタンを押すと、ブラウザがフォームの中の情報を POST メソッドを使ってサーバーに送付します。この裏側で何が起こっているのでしょうか?あなたはここで何もしていないかもしれませんが、裏側でどの HTTP のメソッドを使っているか、サーバーがそれによってどのように反応していることを知るのはサーバーサイドのコードを書く上で非常に役に立ちます。映画をデータベースに追加するコードを書く中で、この意味が分かるようになると思います。

まずは非常にシンプルなフォームから始めたいと思います。見た目は良くありませんが、目的を満たすには十分なフォームです。

 <h1>Add a New Movie to the Database</h1>
  <form action="" method="post">
    <p>Name:<input type="text" name="formName" /></p>
    <p>Genre:<input type="text" name="formGenre" /></p>
    <p>Year:<input type="text" name="formYear" /></p>
    <p><input type="submit" value="Add Movie" /></p>
</form>

これが実行したときの見た目です。

03

それではこのフォームを作成するために記述した HTML を見ていきましょう。

 <form action="" method="post">

まず、ここで新しく出てきたのが <form> タグです。これは入力項目の集合を定義し、ユーザーが送信ボタンを押した場合にそこに含まれるデータを送信するものです。ここではHTTP POST で送信されるように定義されています。また、送信ボタンは必ずフォームの中になければなりません。現在、action 属性が空のままなので、このフォームは自分自身のページに対して要求を送信します。

 <p>Name:<input type="text" name="formName" /></p>
<p>Genre:<input type="text" name="formGenre" /></p>
<p>Year:<input type="text" name="formYear" /></p>

<form> タグの中に3つの <input> タグがあるのに気づくかと思います。<input> タグには何種類かの type 属性が設定できます。この場合ではユーザーがテキストを入力する一般的なテキストボックスを指し示す “text” が設定されています。また、それぞれに name 属性が設定されていて、ユーザーが入力した値をサーバーで扱うための変数のような役割をしています。

 <p><input type="submit" value="Add Movie" /></p>

最後に <input> タグのもう一つの type属性の種類である “submit” を持った <input> タグがあります。これは送信ボタンを定義しています。ユーザーがこの送信ボタンを押したとき、HTTP POST メソッドが実行され、入力したデータがサーバーに渡されます。

今ここで送信ボタンをクリックしたとしても、何も起こりません。それはまだサーバーサイドで POST された要求を処理するコードが掛かれていないからです。

フォームから送られたデータを扱う

フォームを作成した際に、action 属性を空にしたままにしてあります。これは自分自身のページで送信を受け付けるという事を意味しています。

まずは、”AddMovie.cshtml” にページが読み込まれた際に実行する処理を記述します。下記のようなコードをページの先頭に記述します。

 @{
  // Code to execute
}
 
<h1>Add a New Movie to the Database</h1>
<form action="" method="post">
  <p>Name:<input type="text" name="formName" /></p>
  <p>Genre:<input type="text" name="formGenre" /></p>
  <p>Year:<input type="text" name="formYear" /></p>
  <p><input type="submit" value="Add Movie" /></p>
</form>

これまでは、ブラウザ上でアドレスを入力して (もしくは WebMatrix で [実行] ボタンをクリックして) ページを呼び出したていました。この場合は HTTP GET が使われていました。今回、送信ボタンをクリックした場合、action 属性が空であるため、HTTP POST の処理は自分自身を呼びだします。結果的に HTTP GET か HTTP POST の違いだけで同じページを呼び出していることになります。

そのため、そのページが GET を使って呼び出されたのか、POST を使って実行されたのかという事を判別しなければなりません。幸い、.NET Framework ではこの違いを簡単に見分ける仕組みを持ってています。この仕組みを使って If(IsPost) という判定を行い、Treu が帰ってくれば POST で送信されたという事になります。

 @{
  If(IsPost)
  {
    // Do something on the POST
  }
}

フォームを作成した際に、formName、formGenre、formYear という名前を送信するデータそれぞれに付けました。ブラウザがサーバーを呼び出した際に、ブラウザはこの名前を使って'formName=something', 'formGenre=something','formYear=something' といった情報を含むメッセージをサーバーに送信します。

そのため、まずはサーバーサイドでこれらの情報を受け取る変数を定義する必要があります。そして、HTTP POST の中からそれぞれのデータを読み取ります。書いてあることは難しいかもしれませんが、コードとしては非常に簡単です。

 @{
  var MovieName="";
  var MovieGenre="";
  var MovieYear="";
  if(IsPost){
    MovieName=Request["formName"];
    MovieGenre=Request["formGenre"];
    MovieYear=Request["formYear"];
  }
}

ここでMovieName、MovieGenre、MovieYear という3つの変数を設定しました。この3つの変数に送信されたメッセージから取り出したデータを格納しています。次のステップではデータベースに接続してデータを追加するコードを追加します。

データベースに追加する

以前のパートでデータを取得する際に “SELECT” というSQL コマンドを書いてデータベースからデータを取得してきました。今回はデータベースにデータを追加するために “INSERT” という SQL コマンドを使用します。

INSERT の SQL コマンドは次の通りです。

 INSERT INTO Table (Column1, Column2, ...ColumnN) VALUES (Value1, Value2, ... ValueN)

コード内ではどう表現するか見てみましょう。

 @{
var MovieName="";
var MovieGenre="";
var MovieYear="";
  if(IsPost){
    MovieName=Request["formName"];
    MovieGenre=Request["formGenre"];
    MovieYear=Request["formYear"];
    var SQLINSERT = "INSERT INTO Favorites (Name, Genre, ReleaseYear) VALUES (@0, @1, @2)";
    var db = Database.Open("Movies");
    db.Execute(SQLINSERT, MovieName, MovieGenre, MovieYear);
  }
}

SQL コマンドを格納するために SQLINSERT という変数が定義されています。Razor 記法では ”MovieName”、 “MovieGenre”、“MovieYear” といった変数を直接使うのではなく @0、@1、@2 というようにパラメーターを使ってSQL コマンドを組み立てることができます。このコマンドが実行される際に、フレームワーク側で代わりに値を埋めてくれます。また、この記法を使用すると、文字列が SQL コマンドに埋め込まれる前にフレームワークが危険な文字列が含まれていないか検証をし、脅威が検出された場合は文字列に変更 (サニタイジング) を加えてくれます。これはパラメーターの中に別の SQL コマンドを埋め込む “SQL Injection” という攻撃方法を防ぐためです。

次に、データベースをオープンし、データベースに対して INSERTコマンドを実行するために Execute メソッドを呼び出します。ここで本来入るべき変数の値が INSERT コマンドに設定されて実行されます。

さて、もう少し db.Execute() メソッドの後にコードを追加していきましょう。この処理の結果何が追加されたのか確認できるように映画の一覧のページにリダイレクトを書けるようにします。

 Response.Redirect("dataMovies.cshtml");

それでは実行してフォームを表示してみましょう。画面が表示されたらデータを追加してみましょう。

04

“Add Movie” ボタンを押してください。サーバーはデータベースにデータを追加し、結果の一覧を表示します。そして、そこであなたが今追加したものを確認できるかと思います。

05

重要:このパートではユーザーが入力した内容を直接データーベースに追加するように記述しています。学習用途ではこれで問題ありませんが、本番環境で利用する前には次の項目を確認するようにしてください。

- 入力された値が適切な値であるかチェックするコードを追加してください。もし、入力された値が適切でない場合はユーザーに対して適切なフィードバックを表示するようにしてください。たとえば、Year の項目として文字列などの正しくない値が入力された場合、データベースに書き込みに行く前にチェックを行って適切な値でないことをユーザーに知らせてください。

- 入力された情報が悪質な攻撃者によってデータベースを攻撃するためのものでないかのチェックをするコードを追加してください。よくある攻撃手段は SQL Injection と呼ばれるもので、SQL コマンドをフォームとして送信することで、サーバーで悪意のあるコードを実行させ、個人情報の流出などの脅威となりえます。パラメーター化である程度防ぐことはできますが、完全とは言えない点にご注意ください。

WebMatrix におけるデータ処理に関するより詳細はこちらをご確認下さい。(英語):

https://www.asp.net/webmatrix/tutorials/5-working-with-data

まとめ

これで、映画をデータベースに追加する方法を学びました。ユーザーの入力データを扱う HTML フォームを作成し、データベースにデータを追加できるようになりました。また、データの入力が完了したら映画の一覧ページに自動的にリダイレクトをして入力したデータを確認できるようにしました。

次のパートではさらに一歩踏み込んで、ユーザーに既に存在するデータを編集できるようにする機能を追加していきます。