|
今回は「ClickOnceアプリ-Webサービス」という構成で簡単なマスタメンテナンス画面を作成してみます。
実際にDBに接続し、データの取得等も行ってみたいと思います。オラクルのインストール時にデフォルトで
Scottスキーマに入っている「EMP」表を使用します。EMP表のカラム構成は以下ですが、今回は
「EMPNO」、「ENAME」、「JOB」の3つのカラムのみを使用します。プライマリキーは「EMPNO」です。
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
|
作成するClickOnceアプリの画面は以下です。入力された「従業員No(EMPNO)」の従業員が既に存在する場合、
「従業員名(ENAME)」と「職種(JOB)」を表示し、「登録」ボタンが「更新」ボタンに切り替わります。
「従業員No」からフォーカスが外れた時点で、Webサービスに問い合わせを行い、「従業員名」と「職種」を
取得してきます。もちろん、従来のWebシステムのようにその度に画面が再表示される事はありません。
今回は従業員Noから従業員情報を取得するところまでをご紹介し、次回、従業員情報を登録するところ
をご紹介します。
では、Webサービス側のソースから見ていきたいと思います。Webサービス側で作成したクラスは
WebServiceクラスを継承し、[WebMethod]を持つ「EmployeeService」クラスとクライアントとの間で
従業員情報をやり取りするために従業員情報を格納する「Employee」クラスです。Webサービスと
クライアント間のデータのやり取りには「DataSet」クラス等を使用する方法も有りますが、
今回は「Employee」クラスというEntityを使用します。以下が「Employee」クラスのソースです。
「EmployeeService.asmx」
public class Employee
{
private int empNo;
private string empName;
private string job;
public int EmpNo
{
set { empNo = value; }
get { return empNo; }
}
public string EmpName
{
set { empName = value ;}
get { return empName; }
}
public string Job
{
set { job = value; }
get { return job; }
}
}
|
次に[WebMethod]を持つクラスの「EmployeeService」クラスのソースです。
「EmployeeService.asmx」
[WebMethod]
public Employee GetEmployee(int empNo)
{
Employee emp = null;
OracleConnection connect = null;
OracleDataReader reader = null;
//従業員情報を取得するSQL
const String query = "select EMPNO,ENAME,JOB from EMP where EMPNO = :pEmpNo";
try{
connect = new OracleConnection("Data Source=X40;User ID=scott;Password=tiger");
OracleCommand command = new OracleCommand(query,connect);
//従業員Noをパラメータに設定する
command.Parameters.Add("pEmpNo", OracleType.Int32).Value = empNo;
connect.Open();
reader = command.ExecuteReader();
if(reader.Read()){
emp = new Employee();
emp.EmpNo = reader.GetInt32(0);
emp.EmpName = reader.GetString(1);
emp.Job = reader.GetString(2);
}
}catch(OracleException e){
emp.EmpName = e.Message;
}catch(Exception e){
emp.EmpName = e.ToString();
}finally{
try{
if(reader != null){
reader.Close();
}
}catch(Exception e){}
try{
if(connect != null)
connect.Close();
}catch(Exception e){}
}
return emp;
}
|
このソースのポイントは、EMP表から取得したレコードを「Employee」クラスに格納して、クライアントに
返している点です。何か特別な事をする事なく、このように簡単なコードで従業員情報をクライアントに
戻す事ができるのです。
「MainForm.cs」
1: partial class MainForm : Form
2: {
3: public delegate void SetEmployeeInfo(Employee emp); //従業員情報をセットする時に使用するデリゲート
4:
5: public MainForm()
6: {
7: InitializeComponent();
8: //従業員No.フィールドがフォーカスを失った場合のイベントハンドラ
9: tb_EmpNo.LostFocus += new EventHandler(tb_EmpNo_LostFocus);
10: }
11:
12: void tb_EmpNo_LostFocus(object sender, EventArgs e)
13: {
14: try
15: {
16: String value = tb_EmpNo.Text;
17:
18: //従業員Noに入力が無かった場合
19: if (!notNullCheck(value))
20: return;
21:
22: //従業員Noがアルファベットか数字で無かった場合
23: if (!isAlphabetNum(value))
24: {
25: tb_EmpNo.BackColor = Color.DeepPink;
26: return;
27: }
28:
29: tb_EmpNo.BackColor = Color.White;
30: //Webサービスを非同期で呼び出す
31: EmployeeService service = new EmployeeService();
32: service.BeginGetEmployee(Int32.Parse(tb_EmpNo.Text), new AsyncCallback(serviceCallBack), service);
33: }
34: catch (System.Web.Services.Protocols.SoapException ex)
35: {
36: MessageBox.Show("サーバーとの通信に失敗しました。");
37: }
38:
39: }
40:
41: private void serviceCallBack(IAsyncResult ar)
42: {
43: EmployeeService service = (EmployeeService)ar.AsyncState;
44: Employee emp = service.EndGetEmployee(ar);
45: //従業員情報をセットするメソッドを呼び出す
46: Invoke(new SetEmployeeInfo(setEmployeeInfo),new Object[]{emp});
47:
48: }
49:
50: private void setEmployeeInfo(Employee emp)
51: {
52: //従業員が既に存在する場合
52: if (emp != null)
53: {
54: tb_EmpName.Text = emp.EmpName;
55: tb_job.Text = emp.Job;
56: b_ok.Text = "更新";
57: }
58: //従業員が存在しない場合
59: else
60: {
61: b_ok.Text = "登録";
62: }
63:
64: }
65:
66: private bool notNullCheck(String value)
67: {
68: if (value == null)
69: return false;
70: if (value.Length == 0)
71: return false;
72:
73: return true;
74: }
75:
76: private bool isAlphabetNum(String value)
77: {
78: if(value != null)
79: {
80: char[] inputChars = new char[value.Length];
81: value.CopyTo(0,inputChars,0,inputChars.Length);
82:
83: foreach (char c in inputChars)
84: {
85: if (c < '0' || c > '9')
86: {
87: return false;
88: }
89: }
90: }
91:
92: return true;
93: }
94: }
|
12行目から始まる「tb_EmpNo_LostFocus」メソッドで従業員Noがフォーカスを失った場合のイベントを処理します。
まず、入力された従業員Noの半角英数チェック等の基本的なチェックを行い、従業員情報を取得するために
「EmployeeService」を呼び出します。呼び出しは前回の
「Webサービスを非同期で呼び出す」で扱ったように
非同期で行います。Webサービスの処理が終了すると、41行目から始まる「serviceCallBack」
メソッドが呼び出されます。「EmployeeService」から従業員情報が格納された
Employeeクラスのインスタンスが返されます。46行目では、従業員情報を各フィールドに設定するために
さらに「setEmployeeInfo」メソッドを呼び出しています。これはFormのイベントを処理するための
スレッド以外が、Formに置かれている各コントロールにアクセスする事が出来ないため、
(アクセスしようとするとExceptionが発生する)Formのイベントを処理するスレッドから
「setEmployeeInfo」を呼び出させているのです。
次回は従業員情報を登録する部分をご紹介します。
HOMEへ
|