|
連載:Windowsフォーム開発入門【Visual Studio 2010対応】
リモート・データ活用術〜ASP.NET Webサービス編〜
初音 玲
2011/03/09 |
|
業務アプリケーション構築におけるキー・ポイントの1つは、「リモートにあるデータをいかに効率よく活用するか」という点だ。例えば業務アプリケーションでRDBMSがよく使われるのも、リモート・データをデータベース・サーバに蓄積して集中管理することで、効率的にデータを活用できるようにするためだ。
今回はリモート・データを扱う仕組みとして、ASP.NET Webサービス経由でのSQL Serverへのアクセスを想定している。次の図は、本稿で作成するサンプル・アプリケーションにおける、プログラム/ASP.NET Webサービス/SQL Serverの接続関係を表している。
|
図1 サンプル・アプリケーションの動作環境(プログラム/ASP.NET Webサービス/SQL Serverの接続関係) |
プログラムからSQL Serverに直接アクセスする場合に比べて、(ASP.NET Webサービスを経由させることには)どのような利点があり、Windowsフォームの作り方としてどのような点が変わってくるのかを見ていくことにしよう。
■SQL ServerにアクセスするASP.NET Webサービスの作成
まずは、SQL ServerにアクセスするASP.NET Webサービスのプロジェクトを作成する。
Visual Studioの[新しいプロジェクト]ダイアログで[Web]テンプレートの「ASP.NET 空のアプリケーション」を選択して、ベースとなるWebアプリケーション・プロジェクトを生成する。
プロジェクトが生成されたら、[ソリューション エクスプローラー]でプロジェクト項目の右クリック・メニューから[追加]-[新しい項目]を実行する。そこで表示される[新しい項目の追加]ダイアログで「Web サービス」を選択して(図2参照)、新しいASP.NET Webサービスのファイルをプロジェクトに追加する。
|
図2 プロジェクトへのASP.NET Webサービスの追加([新しい項目の追加]ダイアログ) |
作成するWebサービスは、(基本的に)認証を行う「Login.asmx」ファイル(=ログイン・サービス)と、レコードの取得・更新を行う「Titles.asmx」ファイル(=データ入出力サービス)の2つで構成される(図3参照)。
|
図3 画面遷移とWebサービス |
そこで、新しい項目としてこの2つのファイルを追加する。以下では、これらの2つのファイルに対して、ログイン・サービスとデータ入出力サービスを実装していく。
●ログイン・サービス
まずはLogin.asmxファイルに、ログイン・サービスを実装する。具体的には、下記のようなコードになる。
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class Login
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function Check(ByVal userID As String,
ByVal password As String) As Boolean
Dim isOK As Boolean = False
Using _cn As New SqlConnection
Try
_cn.ConnectionString =
String.Format(My.Settings.ConnectonString,
userID,
password)
_cn.Open()
isOK = True
Catch ex As Exception
' 例外をキャッチした場所でログ出力などを行う
Throw ex
End Try
End Using
Return isOK
End Function
End Class
|
namespace WebsSQLCs
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Login : System.Web.Services.WebService
{
[WebMethod]
public Boolean Check(string userID, string password)
{
Boolean isOK = false;
using (SqlConnection _cn = new SqlConnection())
{
try
{
_cn.ConnectionString =
String.Format(WebsSQLCs.Properties.Settings.Default.ConnectonString,
userID,
password);
_cn.Open();
isOK = true;
}
catch (Exception ex)
{
// 例外をキャッチした場所でログ出力などを行う
throw ex;
}
}
return isOK;
}
}
}
|
|
リスト1 ログイン認証を行うWebサービスのコード例(上:VB、下:C#) |
Webサービスのメソッドは、.asmxファイルの中でWebMethod属性を付けたメソッド(上記のコードではCheckメソッド)として定義する。
今回作成したCheckメソッドでは、そのパラメータで指定されたIDとパスワードを使って、SQL Serverに対してSQL Server認証によるログインを実行する。正常にログインできたときは、その戻り値としてTrueを返す。ログインに失敗したときは、ログイン時に呼び出すOpenメソッドが例外を発生させるので、それを呼び出し元にそのままスロー(Throw)している。
●データ入出力サービス ― タイトル検索
次にTitles.asmxファイルに、データ入出力サービス(タイトル一覧の検索/個別のタイトルの検索/個別のタイトルの更新)を実装していく。
データ入出力サービスに実装するWebメソッドの1つ目は、タイトルを検索して一覧データを作成するGetTitleDsメソッドだ。具体的には、LIKE検索のSELECT文を実行して、その実行結果をデータセット(DataSet)に格納して返却する。下記はそのコード例である。
<WebMethod()> _
Public Function GetTitleDs(ByVal userID As String,
ByVal password As String,
ByVal keyword As String) As DataSet
Dim ds As New DataSet
Using _cn As New SqlClient.SqlConnection
_cn.ConnectionString =
String.Format(My.Settings.ConnectonString,
userID,
password)
_cn.Open()
Using _cmd As New SqlCommand
_cmd.Connection = _cn
_cmd.CommandText = "SELECT * " &
"FROM titles " &
"WHERE title LIKE @Title"
_cmd.Parameters.Add(New SqlClient.SqlParameter("Title", "%" & keyword & "%"))
Using _da As New SqlDataAdapter
_da.SelectCommand = _cmd
_da.Fill(ds, "TitleList")
ds.Tables("TitleList").PrimaryKey =
New DataColumn() {ds.Tables("TitleList").Columns("title_id")}
End Using
End Using
End Using
Return ds
End Function
|
[WebMethod]
public DataSet GetTitleDs(String userID, String password, String keyword)
{
DataSet ds = new DataSet();
using (SqlConnection _cn = new SqlConnection())
{
_cn.ConnectionString =
String.Format(WebsSQLCs.Properties.Settings.Default.ConnectonString,
userID,
password);
_cn.Open();
using (SqlCommand _cmd = new SqlCommand())
{
_cmd.Connection = _cn;
_cmd.CommandText = "SELECT * " +
"FROM titles " +
"WHERE title LIKE @Title";
_cmd.Parameters.Add(new SqlParameter("Title", "%" + keyword + "%"));
using (SqlDataAdapter _da = new SqlDataAdapter())
{
_da.SelectCommand = _cmd;
_da.Fill(ds, "TitleList");
ds.Tables["TitleList"].PrimaryKey =
new DataColumn[] { ds.Tables["TitleList"].Columns["title_id"] };
}
}
}
return ds;
}
|
|
リスト2 タイトル一覧を取得するWebサービス(GetTitleDsメソッド)のコード例(上:VB、下:C#) |
前回はWindowsフォームからSQL Serverに接続してデータを取得した。そのとき、データ・アクセス部分は別のクラス・ファイルに分離したが、リスト2を見てもらえば分かるように、その別のクラス・ファイルの中に記述した内容と同じコードで、ASP.NET Webサービスからもデータが取得できている。1つだけ違う点はWebMethod属性を付けたことだ。
●データ入出力サービス ― 1レコード取得
SQL Serverから1レコード分のデータを取得するコードを、Titles.asmxファイルにGetTitleDsItemメソッドとして記述する。
1レコードを取得するためのコード(リスト 3)は、SELECT文のWHERE句としてPK(=主キー)であるtitle_idフィールドの値を指定して検索するという点が異なるだけで、前述の「リスト2 タイトル一覧を取得するWebサービスのコード例」と変わらない。
<WebMethod()> _
Public Function GetTitleDsItem(ByVal userID As String,
ByVal password As String,
ByVal titleID As String) As DataSet
Dim ds As New DataSet
Using _cn As New SqlConnection
_cn.ConnectionString = String.Format(My.Settings.ConnectonString,
userID,
password)
_cn.Open()
Using _cmd As New SqlCommand
_cmd.Connection = _cn
_cmd.CommandText = "SELECT * " &
"FROM titles " &
"WHERE title_id=@TitleID"
_cmd.Parameters.Add(New SqlClient.SqlParameter("TitleID", titleID))
Using _da As New SqlDataAdapter
_da.SelectCommand = _cmd
_da.Fill(ds, "EditTitle")
ds.Tables("EditTitle").PrimaryKey =
New DataColumn() {ds.Tables("EditTitle").Columns("title_id")}
End Using
End Using
End Using
Return ds
End Function
|
[WebMethod]
public DataSet GetTitleDsItem(String userID, String password, String titleID)
{
DataSet ds = new DataSet();
using (SqlConnection _cn = new SqlConnection())
{
_cn.ConnectionString =
String.Format(WebsSQLCs.Properties.Settings.Default.ConnectonString,
userID,
password);
_cn.Open();
using (SqlCommand _cmd = new SqlCommand())
{
_cmd.Connection = _cn;
_cmd.CommandText = "SELECT * " +
"FROM titles " +
"WHERE title_id=@TitleID";
_cmd.Parameters.Add(new SqlParameter("TitleID", titleID));
using (SqlDataAdapter _da = new SqlDataAdapter())
{
_da.SelectCommand = _cmd;
_da.Fill(ds, "EditTitle");
ds.Tables["EditTitle"].PrimaryKey =
new DataColumn[] { ds.Tables["EditTitle"].Columns["title_id"] };
}
}
}
return ds;
}
|
|
リスト3 1レコードを取得するWebサービス(GetTitleDsItemメソッド)のコード例(上:VB、下:C#) |
●データ入出力サービス ― 1レコード更新
SQL Serverにデータを保存する方法はいくつかあるが、本稿のサンプルではデータセットの内容をデータアダプタ(SqlDataAdapter)のUpdateメソッドを使って保存する方法を採用している。詳しくはリスト4(SetTitleDsItemメソッド)を参照してほしい。
<WebMethod()> _
Public Function SetTitleDsItem(userID As String,
password As String,
titleID As String,
ds As DataSet) As Boolean
Dim isOK As Boolean = False
Using _cn As New SqlConnection
_cn.ConnectionString = String.Format(My.Settings.ConnectonString,
userID,
password)
_cn.Open()
Using _tr As SqlTransaction = _cn.BeginTransaction
Try
Using _cmd As New SqlCommand
_cmd.Connection = _cn
_cmd.Transaction = _tr
_cmd.CommandText = "SELECT * " &
"FROM titles " &
"WHERE title_id=@TitleID"
_cmd.Parameters.Add(New SqlParameter("TitleID", titleID))
Using _da As New SqlDataAdapter
_da.SelectCommand = _cmd
Using _cb As New SqlCommandBuilder(_da)
_cb.ConflictOption = ConflictOption.OverwriteChanges
_cb.GetInsertCommand(True).Connection = _cn
_cb.GetInsertCommand(True).Transaction = _tr
_cb.GetUpdateCommand(True).Connection = _cn
_cb.GetUpdateCommand(True).Transaction = _tr
_cb.GetDeleteCommand(True).Connection = _cn
_cb.GetDeleteCommand(True).Transaction = _tr
_da.Update(ds, "EditTitle")
End Using
_tr.Commit()
End Using
isOK = True
End Using
Catch ex As Exception
_tr.Rollback()
Throw ex
End Try
End Using
End Using
Return isOK
End Function
|
[WebMethod]
public Boolean SetTitleDsItem(String userID, String password, String titleID, DataSet ds)
{
Boolean isOK = false;
using (SqlConnection _cn = new SqlConnection())
{
_cn.ConnectionString =
String.Format(WebsSQLCs.Properties.Settings.Default.ConnectonString,
userID,
password);
_cn.Open();
using (SqlTransaction _tr = _cn.BeginTransaction())
{
try
{
using (SqlCommand _cmd = new SqlCommand())
{
_cmd.Connection = _cn;
_cmd.Transaction = _tr;
_cmd.CommandText = "SELECT * " +
"FROM titles " +
"WHERE title_id=@TitleID";
_cmd.Parameters.Add(new SqlParameter("TitleID", titleID));
using (SqlDataAdapter _da = new SqlDataAdapter())
{
_da.SelectCommand = _cmd;
using (SqlCommandBuilder _cb = new SqlCommandBuilder(_da))
{
_cb.ConflictOption = ConflictOption.OverwriteChanges;
_cb.GetInsertCommand(true).Connection = _cn;
_cb.GetInsertCommand(true).Transaction = _tr;
_cb.GetUpdateCommand(true).Connection = _cn;
_cb.GetUpdateCommand(true).Transaction = _tr;
_cb.GetDeleteCommand(true).Connection = _cn;
_cb.GetDeleteCommand(true).Transaction = _tr;
_da.Update(ds, "EditTitle");
}
_tr.Commit();
}
isOK = true;
}
}
catch (Exception ex)
{
_tr.Rollback();
throw ex;
}
}
}
return isOK;
}
|
|
リスト4 1レコードを更新するWebサービス(SetTitleDsItemメソッド)のコード例(上:VB、下:C#) |
SqlDataAdapterのUpdateメソッドは、データセットのデータロウ(DataRow)の状態により内部で自動的にUPDATE文、INSERT文、DELETE文を実行する。そのため、Updateメソッドを実行するときには、下記の2点を忘れずに実施する必要がある。
(1) UPDATE文、INSERT文、DELETE文をSqlDataAdapterに設定する
(2) 明示的にトランザクションを開始し、Updateメソッドが成功したらコミット(Commit)する
(1)の3つのSQL文はコマンドビルダ(CommandBuilder)を使えばSELECT文から自動生成されるし、(2)の明示的なトランザクションもSqlTransactionクラス(System.Data.SqlClient名前空間)を使えば簡単に実装できる。
以上でASP.NET Webサービスが完成したので、続いて、そのWebサービスをクライアント・プログラムから利用する処理を実装する。
INDEX |
|
[連載]Windowsフォーム開発入門【Visual Studio 2010対応】 |
|
リモート・データ活用術〜ASP.NET Webサービス編〜 |
|
1.SQL ServerにアクセスするASP.NET Webサービスの作成 |
|
2.プログラムからのASP.NET Webサービスの利用 |
|