次にWebフォームの分離コードファイルを作成します。リスト7に示すようなprivateメソッド(BindData())を加えます。
private void BindData()
{
List<Photo> photos = PhotoHelper.GetAll();
DetailsView1.DataSource = photos;
DetailsView1.DataBind();
}
BindData()メソッドは、PhotoHelperクラスのGetAll()メソッドを呼び出します。返されたPhotoオブジェクトのジェネリックリストを、DetailsViewにバインドします。Page_Loadイベントは、リスト8に示すように処理します。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindData();
if (DetailsView1.Rows.Count == 0)
{
DetailsView1.ChangeMode(DetailsViewMode.Insert);
}
}
}
ここでは単に、BindData()メソッドを呼び出しています。DetailsViewに表示する行がない場合は、モードを「Insert」に変更します。DetailsViewはデータソースコントロールにバインドされていないため、PageIndexChangingイベントとModeChangingイベントを手動で処理する必要があります(リスト9を参照してください)。
protected void DetailsView1_PageIndexChanging
(object sender, DetailsViewPageEventArgs e)
{
DetailsView1.PageIndex = e.NewPageIndex;
BindData();
}
protected void DetailsView1_ModeChanging
(object sender, DetailsViewModeEventArgs e)
{
DetailsView1.ChangeMode(e.NewMode);
BindData();
}
リスト9のイベントハンドラのコードは簡単なので、説明の必要はないと思います。ユーザーが新しく格納したい写真のデータを入力し、[Insertボタン]をクリックすると、DetailsViewのItemInsertingイベントが発生します。ItemInsertingイベントハンドラはリスト10に示すとおりです。
protected void DetailsView1_ItemInserting
(object sender, DetailsViewInsertEventArgs e)
{
Photo p = new Photo();
TextBox t1=((TextBox)DetailsView1.Rows[0].Cells[1].Controls[0]);
TextBox t2=((TextBox)DetailsView1.Rows[1].Cells[1].Controls[1]);
FileUpload fu=
((FileUpload)DetailsView1.Rows[2].Cells[1].Controls[1]);
p.Title = t1.Text;
p.Description = t2.Text;
Stream imgdatastream = fu.PostedFile.InputStream;
int imgdatalen = fu.PostedFile.ContentLength;
byte[] imgdata = new byte[imgdatalen];
int n = imgdatastream.Read(imgdata, 0, imgdatalen);
p.PhotoData = imgdata;
PhotoHelper.Insert(p);
BindData();
}
ここではDetailsViewに新しく入力された値を取得し、それらをPhotoオブジェクトに代入します。ユーザーがアップロードした写真をバイト配列に変換する方法に着目してください。FileUploadコントロールのInputStreamによって、入力データにアクセスします。そのストリームをバイト配列に読み込みます。最後にPhotoHelperクラスのInsert()メソッドを呼び出して、レコードをPhotosテーブルに追加します。
更新処理は、挿入処理を少し変更するだけです。リスト11に、ItemUpdatingイベントに対するイベントハンドラを示します。
protected void DetailsView1_ItemUpdating(object sender,
DetailsViewUpdateEventArgs e)
{
Photo p = new Photo();
TextBox t1 =
((TextBox)DetailsView1.Rows[0].Cells[1].Controls[0]);
TextBox t2 =
((TextBox)DetailsView1.Rows[1].Cells[1].Controls[1]);
FileUpload fu =
((FileUpload)DetailsView1.Rows[2].Cells[1].Controls[1]);
p.PhotoID = Convert.ToInt32(DetailsView1.DataKey[0]);
p.Title = t1.Text;
p.Description = t2.Text;
Stream imgdatastream = fu.PostedFile.InputStream;
int imgdatalen = fu.PostedFile.ContentLength;
byte[] imgdata = new byte[imgdatalen];
int n = imgdatastream.Read(imgdata, 0, imgdatalen);
p.PhotoData = imgdata;
PhotoHelper.Update(p);
BindData();
}
太字の行に着目してください。DataKeyコレクションを使用して更新する行のPhotoIDを取得し、PhotoHelperクラスのUpdate()メソッドを呼び出しています。
削除処理はとても簡単です。リスト12にそのコードを示します。
protected void DetailsView1_ItemDeleting(object sender,
DetailsViewDeleteEventArgs e)
{
int photoid = Convert.ToInt32(DetailsView1.DataKey[0]);
PhotoHelper.Delete(photoid);
BindData();
}
これでデフォルトのWebフォームが完成しました。次に、写真画像をImageコントロールに供給する「ShowPhoto.aspx」を作成しなければなりません。Webサイトに新しいWebフォームを追加し、「ShowPhoto.aspx」と名づけます。このWebフォームにはコントロールはありません。ShowPhoto.aspxのPage_Loadイベントハンドラは、リスト13のようになります。
protected void Page_Load(object sender, EventArgs e)
{
int photoid = Convert.ToInt32(Request.QueryString["photoid"]);
Photo p = PhotoHelper.GetByID(photoid);
Response.Clear();
Response.ContentType = "image/pjpeg";
Response.BinaryWrite(p.PhotoData);
Response.End();
}
ここではPhotoHelperクラスのGetByID()メソッドを使用して、1つの写真を取得しています。ShowPhoto.aspxは、取得する写真のPhotoIDを指定するクエリ文字列を引数とすることを思い出してください。写真データをRaw形式で格納するバイト配列は、ResponseオブジェクトのBinaryWrite()メソッドを用いて、レスポンスストリームに書き込まれます。書き込む前にResponseをクリアし、ContentTypeを「image/pjpeg」に設定している点に注意してください。
これでWebサイトが完成しました。このデフォルトのWebフォームを実行して、レコードを追加、変更、削除できます。図2は、このWebサイトを実行した例です。

