[著作権者のページTOPに]   [NOP法人日本自費出版ネットワーク]

ASP.NETとSQLサーバーによるWebシステム入門

[この文書はまだ完全ではありません。ご注意ください]

[1] ホームページの作成とWebシステム
[2] Webシステムの構造─どのようにして表示をブラウザに返すのか
[3] ASP.NETを利用したWebシステムの実際
[4] ASP.NETでEメールを送信する
[5] サーバにDB(データベース)を作成する
[6] DBMS(データベース)の利用1 接続して、内容を表示するプログラム
[7] DBMS(データベース)の利用2 接続して、内容を変更・削除・新規登録するプログラム
[8] セキュリテイに配慮した運用システムへ
[9] SQL文の実際活用

[著者について]







■[1]■ ホームページの作成とWebシステム

  [目次に戻る]

ホームページの作成とWebシステム=クラウドコンピューティング

インターネットが日常的な道具になりました。自分でホームページの作成作業を行ったり、仕事や趣味でメンテナンスを行っている方も多いと思います。同じようにインターネットを使いながら、従来のホームページとはひと味違う作業ができる「Webシステム」を作成してみませんか。そのためのツールは「ASP.NETとSQLサーバー」です。プログラミングという操作が入りますので、やや敷居は高くなりますが、楽しみながら順をおって学んでいけばまったく新しい世界が広がってきます。

通常の多くのWebサイトは、html文に代表されるように、エディタなどで作成したいわゆるテキストデータ形式の文書と画像だけで構成されています。これを「静的サイト(static site)」といいます。このhtml文書を「Internet Explorer」や「Google Chrome」、「Mozilla Firefox」などのブラウザで表示するのが通常のホームページと呼ばれるものです。したがって、そこに表示されるページの内容はhtml文に書かれた内容およびそこから呼び出される画像などの「固定した情報=静的情報」になります。制作者側がこのhtml文を書き換えてから再度アップロードし、受け取るほうが再読込をしないと内容は更新されません。

これに対して、ページを開くだけで、以前のページとは内容が更新されている「動的なWebページ」があります。「動的サイト(dynamic site)」といいます。また、Googleなどの検索システムが良い例ですが、検索の結果はいつも違います。あらかじめ検索結果が決まっていて、それを読んでくるわけではなく、検索語に応じて異なったhtml文が自動的に作成され、表示されます。この時、その検索結果が表示されている時のURLをみてみると
 https://www.google.co.jp/search?q=123 

のような文字列が羅列されています。これは「123」という文字列を検索しています。もうひとつ、これは「amazon」での検索例です。

 http://www.amazon.co.jp/s/ref=nb_sb_noss?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&url=search-alias%3Dstripbooks&field-keywords=%E8%89%B2%E5%B7%9D%E5%A4%A7%E5%90%89

このように、ユーザーの問いかけに対して異なった検索結果などを表示する「動的なWebページ」で構成されているのが「Webシステム」です。要するに、あらかじめ決まった「html文書」を呼び出すのではなく、サーバの中に置かれたプログラムで、それに応じた結果のhtml文を自動生成する手法をいいます。自由に投稿できるブログなども「Webシステム」のひとつといっていいでしょう。

これは通常のパソコンなどのアプリケーションで行う業務処理でも同じことです。こつこつと表や文書を作成するのに対して必要な要素を指示するだけで自動的に表やグラフを作成するソフトがあります。同様のことをインターネット上でWebブラウザを通じて行うので「Webシステム」なのです。この場合、利用者としてはブラウザ以外には何も必要がありません。処理やデータ内容はすべて、ネットの向こう側に保管されて必要な処理が行われ 、その結果だけが自分のWebブラウザに表示されるからです。通信速度の向上や処理系の大規模化で、最近ではWebシステムでも大量のデータ検索や専門的な処理が行えるようになりました。いわゆる「クラウドコンピューティング」と呼ばれるものも同じ原理になります。

なお、このようにHTMLを自動的に生成する役割を持つソフトウェアを使用して特定のWebサイトを管理するのがコンテンツ管理システムですが、ここでは「Webシステム」もほぼ同じ意味で使います。


自費出版ネットワーク・自費出版デジタルのWebシステム

最近のこうしたWebシステムでは、JavaScript言語などを使用したユーザインタフェースの開発が行われていて、作成するには大変手間がかかります。しかし、こうした「凝った画面」を使用しないシンプルで基本的なWebシステム機能であれば案外簡単に作成することができます。実際の運用段階ではプログラミング技術と知識が必要ですが、十分に学習できます。人を驚かすデザインや機能は必要ありません。必要で十分な機能をもったサイトをつくることを心がけましょう。

日本自費出版ネットワークと日本グラフィックサービス工業会(JAGRA)が作成した「自費出版ホームページ」と「自費出版デジタルサイト」は、基本的にユーザーの要望に応じた作品の閲覧や購入あるいは新規書籍の登録・修正ができないといけませんので、こうした機能を盛り込んだ「動的サイト(dynamic site)」になっています。

  • http://www.jsjapan.net/index.html=自費出版ホームページ
  • http://www.jsjapan.net/dg/index.html=自費出版デジタルサイト
  • この「自費出版ホームページ」や「自費出版デジタルサイト」の基礎になっている構造を事例として、簡単なWebシステム作成の案内としたいと思います。Webシステムの開発システムにもいくつかの種類があります。自費出版ネットワークでは当初からMicrosoft社の「IIS」を利用した開発を行ってきました。(開発主体者=筑井が同じ言語系に属するVBやVBAでの作業に慣れていたことや、後ででてくるDBについても別の業務システム開発で使用しているので操作に慣れているというのが理由です。「ASP」も当初のスクリプト処理から「ASP.NET」に進化し非常に難しい仕様になってきましたが、開発主体者が当初のシンプルな開発手法からなかなか変化できないもので、そんな開発方法のほうがやりやすい人もいるのではないかというのもこれを書いている理由のひとつです)。

    「ASP」で開発されているWebサイトもかなり多いです。以下がその一例です。Webシステムの開発方法には、このほかにもいくつかの方法があり、RubyやPHPと呼ばれるスクリプト言語も有名です。どれかが特に優れているということはないようです。

  • JR東日本
  • McAfee製品案内
  • symantecstore
  • WebシステムにはDB(DBMS)が欠かせません。上に述べたように、ASP.NETではおなじMicrosoft社のSQLサーバーを使用するのが簡単ですし、ASP.NETを利用できるレンタルサーバー会社は普通SQLサーバーも使えますので、この開発でもSQLサーバーを使用しました。現在のバージョンは2008が多いようです。

    この「自費出版デジタルサイト」は、ASP.NETというマイクロソフトが開発・提供しているWebアプリケーションフレームワークを使用しています。プログラム言語としてはVisual Basicを使用しています。なお、実際の「自費出版ホームページ」や「自費出版デジタルサイト」のメンテナンスについては「別稿」で触れます。






    ■[2]■ Webシステムの構造─どのようにして表示をブラウザに返すのか

      [目次に戻る]


    最初に―windows対応のレンタルサーバーを利用する

    Webシステム作成の大前提としてはセーバーがなくてはなりません。これは自分(自社)で所有し構築する選択肢もありますが、費用やメンテナンスの点で、中小規模では【レンタルサーバー】を利用するのが現実的です。自社でホームページを作成している場合はすでに有料の【レンタルサーバー】をご利用と思いますが、今回は、サーバーのOSがwindowsであることが必要になります。このシステムがwindows専用のIISというインターネット機能を使用しているからです。

    [ホスティング用レンタルサーバーの例-1]
    [ホスティング用レンタルサーバーの例-2]

    最近はwindowsサーバーも増えてきましたが、現在(2016/12)日本自費出版ネットワークのWebシステム部分が利用しているのはwinserverのレンタルサーバーです。どちらもかなり安価なサービスも提供されています。操作方法(管理システム)は少し違いますが、基本的には同じ考えと手法です。

    これらのwindows対応サーバーで紹介している機能の中に「ASP/ASP.NET対応」という説明があるので、今回使用するASP.NETがこのサーバーで使用できるのがわかります。つまり、このサーバーに借りた自分のスペ-スの中に「ASP.NET」のプログラムを記述した特定のファイルを送信してやれば、サーバー側でIISが自動的に起動して、必要な対応を行ってくれるということになります。

    Webシステムの構造─どのようにして表示をブラウザに返すのか

    具体的な内容にはいる前にWebシステムの構造と流れを説明します。大きな流れは大体以下の①②③の3つのパターンになります。

    ①データの送信処理(フォームなどから質問を送り、その情報がユーザーに自動的に送信されるような処理)=DBMSを使用しないこともあります

     指定のHTMLファイル───送信───▶ 【サーバー】
     データの受信 ◀──────────────┘(処理)

    ②データの登録処理(フォームなどから項目別のデータを送り、DBに挿入・新規登録する処理)=DBMSを使用

     新規追加の要求───送信───▶ 【サーバー】
     更新データの受信(フォーム形式)◀──┘(処理)
       ↓
      送信────────────▶ 【サーバー】(処理=DBMSへの登録)

    ③データの変更処理(DB内のデータを呼び出し、それを変更するような処理)=DBMSを使用

     更新の要求───送信─────▶ 【サーバー】 →DBMS
     更新データの受信(フォーム形式)◀──┘(処理)
       ↓
      送信────────────▶ 【サーバー】(処理=DBMSの更新処理)

    まず、一番簡単な①データの送信処理から実際のプログラムの動きをみてみましょう。具体的な事例で示します。

    ●システム作成上の基礎知識1━ASP.NETとは

    先に述べたように、ASP.NET はマイクロソフト社が提供している、Web アプリケーション開発フレームワークで、Webテクノロジーに精通していなくても比較的簡単にWebアプリケーションが開発できるというのが「うたい文句」です。まずは「ASP.NETページ」を書いてみましょう。

    以下のテキスト文書を「sample-1.aspx」という名前をつけて作成してください。このとき、文字コードを「UTF-8」のファイルで保存します。このコードの実行環境がそうなっていますし、また、現在のブラウザは「UTF-8」を基本エンコーディングとしているものが多いからです。HTNファイルLやプログラムもすべて「UTF-8」を基本として作成したほうがいいでしょう。
    このファイルをIIS でアクセスできる場所に保存します。Windwsサーバーを借りた場合はなら、FTPソフトで転送してください。

    <%@ Page ContentType="text/html" Language="VB" %>
    <html>
    <body>
    <p>
    <% 
         Response.Write("こんにちわ!") 
    %>
    </p>
    </body>
    </html>
    

    ブラウザからこのページ(例:http://www.longview.jp/list/sample-1.aspx)を実行すると、次のような結果になるはずです。

    こんにちわ!
    

    そして、ブラウザの「ソースを表示」でこのHTMLを見ると次のようになっているはずです。

    <html>
    <body>
    <p>
    こんにちわ!
    </p>
    </body>
    </html>
    

    元のソースコードと生成された HTML を見比べると、HTML では <% と %> で囲まれた部分がなくなっていることがわかります。ASP.NET では <% と %> で囲まれた部分にはVBなどでのプログラミングコードや ASP.NET 特有の制御文字列が記載されています。ASP.NET ページをもう少し詳しく、まずは、先頭行を見てみます。

    <%@ Page Language="VB" %>
    

    この部分は「ページディレクティブ」と呼ばれて、そのページの属性等を指定します。これは必ずASP.NETページの先頭に記載します。ここではVBを使用していますが、 Language="C#" と書くことによって、「このページに記述されるプログラミング言語を C# とする」こともできます。
    つぎの「<%@ Import Namespace="System.Data" %>」や「<%@ Import Namespace="System.Data.SqlClient" %>」も同じで、いずれもMicrosoft .NET Framework クラス ライブラリの名前空間を参照しています。階層は以下のようになっているそうですが、私もよくはわかりません。

    System.Object
      System.Web.UI.Control
        System.Web.UI.TemplateControl
          System.Web.UI.Page
            System.Web.UI.DataVisualization.Charting.ChartHttpHandler
            System.Web.UI.MobileControls.MobilePage
    

    この中の「System.Web.UI.Page」クラスが、ASP.NET Web アプリケーションのホストであるサーバーから要求された「aspxファイル」を解釈し表示します(ASP.NET の既定の設定では、ファイルの拡張子は .aspx とします)。このファイルは Webフォームページとも呼ばれます。先ほどのResponse はこの System.Web.UI.Page のプロパティです。Response プロパティは現在のコンテキストの HttpResponseオブジェクトを返します。HttpResponse クラスには Write メソッドがあり、これによってクライアントへデータを返信することができるのです。


    通常は、以下の設定でデータの表示は可能です。

    <%@ Page Language="vb" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    

    <% 
         Response.Write("こんにちわ!") 
    %>
    

    述べたように、この部分は Response.Write というASP.NETメソッドを使って、クライアントに文字を出力しています。 このため、ASP.NETを実行した結果生成される HTMLには、 Response.Write メソッドへ渡した文字列である "こんにちわ!!" が書き込まれています。
    以上が、最も単純な ASP.NETページです。いかがでしょうか。 要は <% と %> の中にコードを書いていけばよいのです。

    このようにシンプルな使い方の場合には通常の文字処理を行えるようなテキストエディタでも作成しても十分実用になります。このほかに、ASP.NETの開発には、Visual Web Developer 2010 Expressという専用の開発ツールもあり、異なる開発の方法があります。

    この開発手法については「 セキュリテイに配慮した運用システムへ」でも解説しています。

     ●システム作成上の基礎知識2―サーバ・コントロールの使用

    ・次に以下のようにこのプログラムを書き換え、「sample-2.aspx」として保存します。

    <%@ Page ContentType="text/html" Language="VB" %>
    <script runat="server">
    	Sub こんにちわ()
    		Response.Write("こんにちわ!") 
    	End Sub
    </script>
    
    <html>
    <body>
    <p>
    <% 
        Call こんにちわ()
    %>
    </p>
    </body>
    </html>
    

    ブラウザからこのページ(例:http://www.longview.jp/list/sample-2.aspx)を実行するとどうなるでしょうか。

    結果は全く同じです。この場合、「runat="server"」が指定されたエレメント(この場合はこの部分のスクリプト)だけがASP.NETエンジンの処理対象になっていることが分かるはずです。このような「runat="server"」が指定された、いわばHTMLの拡張エレメントは、「サーバ・コントロール」と呼ばれる部分です。サーバ・コントロールには、 [1]formエレメントのように、HTMLでも定義されているエレメントにrunat属性を追加したHTMLサーバ・コントロール、と [2]asp:ListBoxエレメントのようにASP.NETで定義されているWebサーバ・コントロール―があります。ASP.NETは通常、[2]の拡張されたHTML形式のサーバ・コントロールを使用していくように解説されています。しかし、ここでは、なるべく簡単な形式での作成と表示を重用しますので、あまりこの機能を使いません(次章で説明)。






    ■[3]■ ASP.NETを利用したWebシステムの実際

      [目次に戻る]


    「ASP.NET」で作成するASPXファイル

    前回、ファイル名を「ASPX」として作成したファイルをwindowsサーバーに送ってその結果をみました。いわゆるASP.NETを利用したWebシステムの処理です。これをもう一度説明しておきます。繰り返しですが、PHPなど他のWeb開発システムでも同様の流れになります。

    1. ユーザーが、このASP.NETページ(ファイルの拡張子が「ASPX」です)を実行すると、サーバーに実装されているMicrosoft社のWebサーバソフト「IIS」が起動します。これにより、ASP.NET機能によって <% ~%> までのASP.NETページが解析され作成された内容が、最終的には、通常のHTML文に変換されてユーザーそれぞれのブラウザへと転送されます。
    2. また、開始タグの属性に「runat="server"」が指定されたスクリプト要素も適切なHTML要素に置換されて、ユーザーのブラウザに出力されます。この「runat="server"」が指定された、いわばHTMLの拡張エレメント部分に「サーバ・コントロール」と呼ばれている独特の部品を配置したり、コントロールを操作したときの処理内容(イベントドリブン)を記述できます。ASAP.NETではこの処理をグラフィカルに行う方法が通常のようです。
    3. ただし、私の作成しているASP.NETページでは、実は、この独特のサーバコントロール(ASP.NET独自のHTML拡張部品)をあまり使いません。「Resposnwrite コマンド」で通常のHTML文を作成していきます。これは旧バージョンのASPによく似た方法ですが、これで問題はありませんし、むしろ初心者には簡単に理解できると思います。ASP.NETで定義されているWebサーバ・コントロールを使った処理を本格的に勉強されたい方には、たくさんの入門書やWebサイトがありますので、そちらをご覧ください。

    さて、この方法でのプログラム処理をよく理解するために、前回の作成したフォーム送信用のhtml文を少し修正してみます。このフォーム文のソースを見ると、前回とは違い、POST先に「http://www.jswork.jp/jsmenber/jstest-4.aspx」とあります(フォルダをjsmemberに変更しました)。

    フォームに記入して「送信」ボタンを押してください。


    (氏名、電話を必ず記入してください-1)

    氏名:
    電話番号:

    修正してあらかじめサーバーに送っておいた、この「jstest-4.aspx」の内容はこうなっています。

    jstest-3.aspx
    
    <%@ Page ContentType="text/html" Language="VB" validateRequest="false" Debug="true"%>
     <script runat="Server">
    	Dim strName
    	Dim strTelNo
    	Sub ResponseData()'----------------------------------
    			strName=request.form("name")
    			strTelNo=request.form("tel")
    		If String.IsNullOrEmpty(strName) = True Then
    			Response.Write("<p>氏名がありません!  </p>" & vbCrLf)
    		ElseIf String.IsNullOrEmpty(strTelNo) = True Then
    			Response.Write("<p>電話がありません!  </p>" & vbCrLf)
    		Else
    			Response.Write("<p>・氏名は:" & strName & "</p>" & vbCrLf)
    			Response.Write("<p>・電話は:" & strTelNo & "</p>" & vbCrLf)
    		End If
        End Sub
    </script>
    <html>
    <head>
    <meta http-equiv='content-type' content='text/html; charset=UTF-8' />
    <title></title>
    </head>
    <body>
    <%
    	Call ResponseData
    %>
    </body>
    </html>
    

    このソースプログラムを順に解説してみます。なお、ここで使用している言語はVB(Visual Basic)です。C#など他の言語で書いても、サーバーに送られた後でコンパイルされて実行結果は同じになります。

    1 最初の

     Dim strName
     Dim strTelNo
    

    は変数の定義です。変数を使用することはプログラムの基本中の基本です。ASP.NETでは通常は(As Stringなど)のように指定する文字型、数値型の他に、この例のように、特定の型を指定しないでどんなデータも収容するバリアント型があります。

    2 次の

     strName=request.form("name")
     strTelNo=request.form("tel")
    

    は、この変数に、ユーザーがフォームからPOSTメソッドで送信したデータを代入します。こうして、サーバーサイドでは、ユーザーが指定したデータをもとにして次の処理ができるようになります。

    次の処理ロジックは、前回のように単純に送られてきたデータを返すのではなく、そのデータが目的に添っているかどうかを確認するという役目を行います。

    	If String.IsNullOrEmpty(strName) = True Then
    		Response.Write("<p>氏名がありません!  </p>" & vbCrLf)
    	ElseIf String.IsNullOrEmpty(strTelNo) = True Then
    		Response.Write("<p>電話がありません!  </p>" & vbCrLf)
    	Else
    		Response.Write("<p>・氏名は:" & strName & "</p>" & vbCrLf)
    		Response.Write("<p>・電話は:" & strTelNo & "</p>" & vbCrLf)
    	End If
    

    ここで「String.IsNullOrEmpty」という関数を使用しています。プログラムでの関数(これまたプログラムの基本)とは、引数と呼ばれる文字や数値のデータを受け取り、定められた通りの処理を実行して結果を返す一連の命令群のことをいいます。大部分のプログラム言語には似た機能の関数があります。関数はたくさんありますし、既製の関数を組みあわせて独自の関数を作成することもできます。例えば、VBの文字処理では以下の例は、既製(あらかじめ言語に組み込まれたもの)です。

     
    ・文字数 Len関数
    ・文字の切り出し Mid関数
    ・文字種の変換 StrConv関数
    ・文字の置換 Replace関数
    

    実際にはこうした機能を使って様々な処理を行います。例えば
     電話の文字数を計算して、10文字以下なら警告する。

    If Len(strTelNo) < 10 Then
    	Response.Write("電話番号を確認してください" & vbCrLf)
    End If
    	strTelNo = StrConv(strTelNo,vbNarrow)	'電話番号をすべて半角にする。
    	strTelNo = Mid(strTelNo,1,15) 	'電話番号を15文字以内にする
    	strName = Mid(strName,1,5) 	'氏名は5文字以内にする
    </pre> 
    

    この処理を行う「jstest-4.aspx」を組み込んだフォームが次です。

    (氏名、電話を必ず記入してください)

    氏名:
    電話番号:

    このように文字数や文字の種類などを変更するのは、ひとつには正しいデータを得るためですが、もうひとつ、不特定多数のユーザーからのアクセスを受けるWebシステムでは、悪意のある攻撃に備えるという意味があります。ここまで作成した処理は、送ってきた内容を単純に(送信者自身に)送り返すだけの処理ですから大きな問題はありませんが、これが、これから述べるように、サーバーの中のDBを書き換えるような処理の場合には非常に危険なことになります。

    したがって、ユーザーから送信されたデータはすべてチェックして、危険な要素を削除する必要があります(SQLインジェクション対策)。細かいことはいちいち表示しませんが、実際にはやっています。こうしたセキュリテイについては、最後の第8章 セキュリテイに配慮した運用システムへをご覧ください。






    ■[4]■ Eメールを送信する

      [目次に戻る]


    ASP.NETでEメールを送信する

    Webシステムの中で重要性の大きいが、サーバーからユーザーへのEメールの送信です。Eメールを返信することで、送信された情報を受け取ったことをユーザーに知らせると同時にそのEメールが本当に自分自身で送信したものかどうかを確認する方法は本人確認の確実な方法として頻繁に使われています。自費出版デジタルでも、申込・登録・修正のすべてにわたって、このEメールによる本人確認システムを使用しています。

    使用しているのがレンタルサーバーの場合には、ユーザーから送信された情報を(物理的に)離れた場所にいる実際の管理者にEメールで送信することもあります。もちろん、あらかじめ登録してあるリストにもとずいて同時にたくさんのEメールを送信するような使い方も多いと思います。

    このように利用する機会の多いEメール送信はどのようにやるのでしょうか。ASP.NETの場合は、私は2つの方法を使用しています。1つは旧ASPのころから利用している「BASP21」という通信コンポーネント(フリーソフト)を使用しています。ローカル環境でも利用可能で、これをVBAなどでオブジェクトで呼び出して使用します。詳細はこちらをご覧ください。

    [http://www.hi-ho.ne.jp/babaq/basp21.html]

    また、以前のVB標準の組み込みオブジェクトでは実現不可能な機能ももっていて便利だったのですが、現在では無料版の開発は止まっていることと、Windowのレンタルサーバーでも費用の安いコースの場合は対応していない場合がありますので、ここでは、ASP.NETの標準機能である「SmtpMailクラス(System.Web.Mail名前空間)のSendメソッド」を使用したEメール送信を行います。

    とりあえず、実例を見てみましょう。以下のようなフォームからデータを送信します。Eメールアドレスには必ず自分のアドレスを入力してください。

    (氏名、電話を必ず記入してください-1)

    氏名:
    電話番号:
    Eメールアドレス:

    あらかじめサーバーに送っておいた、この「jstest-6.aspx」の内容はこうなっています。

    <%@ Page Language="VB"  ResponseEncoding="utf-8" %>
    <%@ Import Namespace="System" %>
    <%@ Import Namespace="System.Web" %>
    <%@ Import Namespace="System.Web.Mail" %>
    
    <script runat="server">
    
    	Dim strName
    	Dim strTelNo
    	Dim strEmail
    	Dim BData
    	
    	Sub SendMail()
           
    		strName=request.form("name")
    		strTelNo=request.form("tel")
    		strEmail=request.form("EMail")
    
             If String.IsNullOrEmpty(strEmail) = True Then
                 Response.Write("<p>Eメールがありません! </p>" & vbCrLf)
                 Exit Sub
             ElseIf String.IsNullOrEmpty(strName) = True Then
                 Response.Write("<p>氏名がありません! </p>" & vbCrLf)
                 Exit Sub
             ElseIf String.IsNullOrEmpty(strTelNo) = True Then
                 Response.Write("<p>電話がありません! </p>" & vbCrLf)
                 Exit Sub
             End If
    
            BData= "・氏名:" & strName & vbCrLf & "・電話:" & strTelNo
            BData = "(自動送信されています)" & vbCrLf & vbCrLf & "以下の連絡を受け付けました。" & vbCrLf & vbCrLf & BData
    
            Dim Mailer As MailMessage
    
    	'----ユーザーに確認の送信
    	
            Mailer = New MailMessage()
            Mailer.From = "pu8n-tki@asahi-net.or.jp"
            Mailer.To = strEmail
            Mailer.Subject = "送信テスト"
            Mailer.BodyEncoding = Text.Encoding.GetEncoding("ISO-2022-JP")
            Mailer.BodyFormat = MailFormat.Text
            Mailer.Body = BData
            Mailer.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
            Mailer.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = "*****01"
            Mailer.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "*****02"
            SmtpMail.SmtpServer = "mail.asahi-net.or.jp"
            SmtpMail.Send(Mailer)
            Response.Write("<p>[確認のEメール情報を送信しました]</p>")
    
    	End Sub
    
     </script>
    <html>
    <head>
    <meta http-equiv='content-type' content='text/html; charset=UTF-8' />
    <title></title>
    </head>
    <body>
    <%
    	Call SendMail
    %>
    </body>
    </html>
    
    

    このソースプログラムを順に解説してみます。以前に説明した変数などは省略しますが

    	strName=request.form("name")
    	strTelNo=request.form("tel")
    	strEmail=request.form("EMail")      
    

    などはおわかりと思います。

    次がVBで「SmtpClientクラス」を使ってメールを送信する方法です。

    	mail.To には、送信先のEメールid(この場合は、筑井のEメール)
    	mail.Fromには、送信元のEメールid(この場合は、送信者のEメール)
    
    が入ります。また

    	Mailer.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = "*****01"       
    	Mailer.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "*****02"
    

    がSMTPサーバの認証IDとパスワード設定です。「*****01」には、実際のユーザー名、「****02」には実際のパスワードを記述します。

    ようするに自分が使用しているメールソフトの設定を記述して、サーバーから代理で送信するという考え方です。私の場合は「mail.asahi-net.or.jp」を使用しました。当然有効な送信サーバーでなければいけません。







    ■[5]■ サーバにDB(データベース)を作成する

      [目次に戻る]

    データベースを理解する

    本題に入る前に、Web環境であれ、ローカル環境であれ、まずはデータベースというものを理解していないと話が進みません。データベースソフトと呼ばれるもはMS-DOSの時代からあり、使用していた方も多いと思いますが、最近ではマイクロソフトオフィスの中の表計算ソフトである「EXCELL」が簡易的なDBとして使えるので名簿やリスト作成に利用している方が多いと思います。確かに、最近の「EXCELL」は、データの並べ替えやLOOKUPなどの高度な関数を使ってかなりの処理を行えます。しかし、複数のデータを結合したり、多くの人が同時に使用したりする場合の堅牢さや処理の自由度などを考えると、今でもこのDBDMSと呼ばれるシステムが業務処理の世界では基本になります。

  • DBMSについての基本情報
  • 特にリレーショナル(関係)型といって、複数のテーブルを利用して操作を行うデータベースシステムが基準になります。このリレーショナルデータベースを管理するためのソフトウェアを関係データベース管理システム (RDBMS) と呼びます。具体的に製品名をあげると、Oracle Database、Microsoft SQL Server、MySQL、PostgreSQL、DB2、FileMaker、H2 Database などが名高いものです。MySQLやPostgreSQLはオープンソースで公開されている製品です。

    この解説のなかで使用するWebシステムはMicrosoftの「SQL Server(MS SQL)」というDBMSです。これがレンタルサーバーの中にインストールされていて、ユーザーはそれをインターネットの回線を通じて遠隔操作することになります。また、自分のパソコンなどのローカル環境にこの製品を置いておき、ACCESSなどのフロントエンドと呼ばれるソフトから自由に使うこともできます。(私は管理工学研究所の「桐」というソフトを古くから使っていますが、バージョン8以降ではODBS接続することによって「外部データ」としてこの「SQL Server」に接続することができ、コマンドによるプログラムも可能です)

    ありがたいことに、この「SQL Server」には、無償で利用できる「Express Edition」よばれるバージョンがあります(実際には、Express Edition with Advanced Servicesという、管理ツールも付属したバージョンを選びます)。SQL Serverは最新版を利用したほうがいいかもしれませんが、私は現在(2015/03)時点で、サーバーサイドでも使用されている「2008R2」というバージョンを利用しています。以下がリンク先ですので、説明をお読みの上、最適なバージョンを選んでダウンロードし、インストールしてください。無償バージョンとはいえ、数人~数十人規模で使用するには十分の性能をもっていますので、中小企業のシステムには十分使えます(実際、使っています)。

  • 2008R2のダウンロード
  • ・SQLサーバー2008 R2の実際のインストールで築いた点をあげておきます。 /p>

    ①インストーラで開始。
    ②インスタンスの作成→既定([サーバ名\\SQLEXPRESS]となる)とする。
    ③混合認証 パスワードを ****** とする。
    ④SQLSERVAR browserを自動起動の設定にする。

    ・インストール後

    ①構成マネージャーで「SQLEXPRESS]のプロトコル→TCP/IP→有効→TCP動的ポートを0(有効)とする。
    ②SQL Server Management Studio (SSMS)のプロパティ→接続→「このサーバーへの接続を許可するをチェック。」
    ③[テーブルの再作成を必要とする変更を保存できないようにする] オプションを変更する(以下の手順を実行)
    SQL Server Management Studio (SSMS)  [ツール] メニューの [オプション] 。
    [オプション] ウィンドウのナビゲーション ウィンドウで、[デザイナー] をクリック。
    [テーブルの再作成を必要とする変更を保存できないようにする] チェック ボックスをオフにして、[OK] 。
    ④コントロールパネルの「windows ファイアウォール」の設定が有効の場合は例外にSQLSERVER.EXEを追加。この場合、詳細設定で「ローカルエリア接続」をチェックしない。

    以下のページに、SQLサーバー発売元のmicrosoft.comからのテキストがあります。最新版2012のテキストになっていますが、基本的な方法は2008とほぼ同じなので参考になります。

  • SQLサーバーの自習書
  • なぜWebシステムでDBMS(データベース・マネージメント・システム)を使用するか

    通常の情報システムでもDBMS(データベースマネジメントシステム)は重要な役割を果たしますが、Webシステムの中でもこのDBMSの利用が欠かせません。銀行やショッピングサイトなどで利用されることは当然ですが、会員管理や商品管理など、おそらく少し大きなWebサイトでDB(データベース)を利用していないシステムはないといってもいいでしょう。この大事なDB機能を利用するためには

    1. 必要なDBを使用することができるサーバを選択する
    2. サイトに接続して、必要なプログラムを製作し、http通信を利用して送受信する
    が必要です。自費出版ネットワークでも「会員管理」や「登録書籍の管理」などメインの作業は、DBに登録したデータを検索したり表示したりして実現しているものです。 以下の実例で説明します。
  • 東京の会員を表示 http://jswork.happywinds.net/jsindex/introduct.aspx?code=5131
  • 特定の書籍を表示 http://jswork.happywinds.net/jsindex/jsbookview-n.aspx?NO=07950
  • 地域文化部門の書籍を表示 http://jswork.happywinds.net/jsindex/jssubjectindex.aspx?subject=%2801%29
  • いずれも通常のHTMLページではなく、特別のマークを付けたページを呼び出していることがわかります。たとえば「code=5131」は、自費出版ネットワーク会員データベーステーブルの中から都道府県コードが「5131」の会員だけを選択して表示しなさいという命令をサーバに送っていることになります。このように、データベースを利用するのは、前回までのようにプログラムを記述して、命令文の中に必要なデータを組み込んでおき、その内容によってDBの中から最適なデータを呼び出し、表示させているということになります。

    ●DBを使用することができるサーバを選択する

    レンタルサーバーは数多くありますが、DBやサーバ側でのプログラミングを可能にするものとして、ここでは先に紹介したレンタルサーバーでも使用方法を例にとって説明していきます。

    ●実際にWeb内にデータベースを作成する

    これは実際の事例をみていただきましょう。


    [ホスティング用レンタルサーバーの例(その1)]

    こちらはWebベースの管理システムを使用する例です。


    図-1 管理ソフト「SqlServer ManagementStudio」のログイン画面


    図-2 クエリー画面から、テーブルの作成SQL文を実行する(デスクトップ版とほぼ同じ操作です)


    [ホスティング用レンタルサーバーの例(その2)]

    こちらはWebベースの管理システムを使用する例です。

    図-3  ホスティングサービスへのログイン画面(上)



    図-4 データベースシステムの選択画面

    図-5 クエリー画面から、テーブルの作成SQL文を実行する







    ■[6]■ DBMS(データベース)の利用1 接続して、内容を表示するプログラム

      [目次に戻る]

    データベース(DBテーブル)に接続する

    まず、作成したテーブル<SYOLIST>に接続して、内容を表示するプログラム[OpenList.aspx]を作成します。

    <%@ Page ContentType="text/html" Language="VB" validateRequest="false" Debug="true"%>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    
    <script runat="server">
        
        Sub OPENLIST()
    
            Dim NAME, BTITLE, SYOMEI As String
            Dim strSQLdata As String
    
            strSQLdata = "SELECT * FROM SYOLIST"
    
            Dim objDb As New SqlConnection("Server=dwprdb01.dataweb.ne.jp;Database=LIST;UID=****;PWD=****")
            Dim objCom As New SqlCommand(strSQLdata, objDb)
    
            objDb.Open()
    
            Dim dr As SqlDataReader = objCom.ExecuteReader()
       
            If dr.HasRows = True Then 'データがある
    
                Response.Write("<table width='840' border='1'><tr><td>")
     
                While (dr.Read())
    
                    BTITLE = dr("書名")
                    SYOMEI = dr("賞名")
                    NAME = dr("著者名")
     
                    Response.Write("<tr><td>")
                    Response.Write(SYOMEI)
                    Response.Write("</td><td>")
                    Response.Write(BTITLE)
                    Response.Write("</td><td>")
                    Response.Write(NAME)
                    Response.Write("</td></tr>" & vbCrLf)
     
                End While
     
                Response.Write("</table>")
     
                dr.Close()
                objDb.Close()
            End If
    
        End Sub
    
     </script>
    
    <html>
    <head>
    <meta http-equiv='content-type' content='text/html; charset=UTF-8' />
    <title>LISTの表示</title>
    </head>
    <body>
    
    <%
        Call OPENLIST()
    %>
    
    </body>
    </html>
    

    ここで大事なのが最初に出てくる

           Dim objDb As New SqlConnection("Server=dwprdb01.dataweb.ne.jp;Database=LIST;UID=******;PWD=****")  
           Dim objCom As New SqlCommand(strSQLdata, objDb)
    

    です。「接続文字列」といいますが、サーバーに置かれたSQLデータベーズを指定して以下の処理を行います。この「接続文字列」のサーバー部分は各レンタルサーバによって異なりますので、開設時に指示してもらいます。次のDatabase名やUID(ユーザーID)、PWD(パスワード文字列)は、実際にデータベースを作成するときに利用者が設定するものです。

            objDb.Open()
    
            Dim dr As SqlDataReader = objCom.ExecuteReader()
     
            If dr.HasRows = True Then 'データがある
    
               While (dr.Read())
                    BTITLE = dr("書名")
                    SYOMEI = dr("賞名")
                    NAME = dr("著者名
             ~~~~~~~~~~~~~~(略)
              Response.Write(SYOMEI)
    
    

    これで、作成したDBオブジェクトを開き、データがあった場合には、それを変数に入れています。あとはこれを表示するだけです。
    以下がこの処理を行い、DBの内容を紹介する実際のプログラムです。

     ・http://www.longview.jp/list/OpenList.aspx

    次回以降は、この接続環境で実際のDBを利用するためのプログラムを解説します。







    ■[7]■ DBMS(データベース)の利用2 接続して、内容を変更・削除・新規登録するプログラム

      [目次に戻る]

    ここでは実際にDBのデータを変更したり追加したりするための<ASP.NET>でのWebプログラムを紹介します。いずれも前回でのDB接続方法を利用してに、さらに、UPDATEやINSERTといった「SQL構文」を利用してデータの追加や更新を行います。

    データベースのデータを変更・削除する

    前回作成したサーバー上のテーブル<SYOLIST>を例にして、処理プログラムの事例を研究します。まず、以下のASPXファイルを実行してみてください。サーバー内容のテーブル<SYOLIST>の内容を呼び出し、1レコードごとに、その内容を書き換えたり、削除したりするためのWebプログラムです。


     http://www.longview.jp/list/listupdate1.aspx

    ● listupdate1.aspxの内容

    <%@ Page ContentType="text/html" Language="VB" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ import Namespace="System.IO" %>
    
    <script runat="Server">
    
    Sub OPENDATA()
    
    	Dim NAME, BTITLE, SYOMEI As String
    	Dim strSQLdata As String
    	Dim KAISU, NO As VariantType
    
    	strSQLdata = "SELECT * FROM SYOLIST"
    
    	Dim objDb As New SqlConnection("Server=dwprdb01.dataweb.ne.jp;Database=LIST;UID=TSUKUINOBUAKI;PWD=jsjapan#JS")
    	Dim objCom As New SqlCommand(strSQLdata, objDb)
    
     objDb.Open()
     
     	Dim DR As SqlDataReader = objCom.ExecuteReader()
     
     If DR.HasRows = True Then   '-- データがある
     Else                        '-- ない
     	Response.Write("<center>データがありません。</center><br>" & vbCrLf)
     	Response.Write("<br><center><form><font size='2'><input type='button' value='戻る' 	onclick='history.back()'><br></font></form></center>" & vbCrLf)
    	 DR.Close()
    	 Exit Sub
                
     End If
    
    While (DR.Read)
    
      Response.Write("<form method='POST' action='LISTUPDATE2.ASPX' onsubmit='return' name='NSOKFORM'>")
      Response.Write("<table widrh='840' border='1'>" & vbCrLf)
    
      KAISU = DR("回数")
      BTITLE = DR("書名")
      SYOMEI = DR("賞名")
      NAME = DR("著者名")
      NO = DR("NO")
    
     Response.Write("<p>" & vbCrLf)
     Response.Write("<tr><td>")
     Response.Write("<input type='hidden' name='NO' value='" & NO & "'>" & vbCrLf)
     Response.Write("回数:<input type=text name='KAISU' size='60' value='" & KAISU & "'>" & vbCrLf)
     Response.Write("</td></tr><tr><td>")
     Response.Write("書名:<input type=text name='BTITLE' size='60' value='" & BTITLE & "'>" & vbCrLf)
     Response.Write("</td></tr><tr><td>")
     Response.Write("賞名:<input type=text name='SYOMEI' size='60' value='" & SYOMEI & "'>" & vbCrLf)
     Response.Write("</td></tr><tr><td>")
     Response.Write("著者名:<input type=text name='NAME' size='60' value='" & NAME & "'>" & vbCrLf)
     Response.Write("</td></tr><tr><td>")
     Response.Write("</tr></td></table>")
     Response.Write(" <input type='checkbox' name='sakuzyo' value='ON'><b>削除</b>(注意)" & vbCrLf)
     Response.Write(" <input type=submit value=更新></form> [NO:" & NO & "]" & vbCrLf)
     Response.Write("<p>" & vbCrLf)
    
    End While
    
     DR.Close()
     objDb.Close()
    
     Response.Write("<dl><li><font color='red'>[実行]の前に再確認!</font> ご覧のデータに更新あるいは削除されます。</dl>" & vbCrLf)
     Response.Write("<center><form><input type='button' value='戻る'  onclick='history.back()'></font></form><br>" & vbCrLf)
     Response.Write("<center>更新が可能です。<br></center><br>" & vbCrLf)
    
    End Sub
    
    </script>
    
    <html>
    <head>
    <meta http-equiv='content-type' content='text/html; charset=UTF-8' />
    <meta http-equiv='Content-style-Type' content='text/css' />
    <link href="http://junosaitama.expressweb.jp/topm.css" rel="stylesheet" type="text/css">
    </head>
    <title>変更削除</title>
    <body>
    
    <%
    	CALL OPENDATA
    %>
    
    </body>
    </html>
    
    

    Webページ間での情報のやりとり

     ◆ <Request.Form コレクション>を使用する方法

    この処理では実際の修正を行うには、記述された<listupdate1.aspx>から別のWebページ<listupdate2.aspx>を呼び出しています。この時に<listupdate1.aspx>に入力されたユーザーの情報を新しいページ<listupdate2.aspx>に転送する必要があります。インターネットのhttp通信は1回ごとに切れるのが原則だからです。このため通常は(ASP.NETに限らずどのシステムでも)Webページの間で情報をやりとりするためのいくつかの方法が用意されていますが、ここでは、旧ASPの時代から利用されていた<POST>メソッドで送った情報を、転送先のWebページの<Request.Form コレクション>で受け取る方法を使用しています。

    <submit>ボタンがクリックされることにより、<action属性に記述されているページ>が呼び出され、テキスト・ボックスで入力されている文字列値がサーバへ送信されます。「データをポストする」とは、フォームの実行(submit)によるデータが送信されるといいう意味です。隠しフィールド<hidden属性>により埋め込まれた値(画面にはあらわれない)も送信できます。ここではASPXで作成していますが、送信側は通常のHTML文かまいません。

          Response.Write("書名:<input type=text name='BTITLE' size='60' value='" & BTITLE & "'>" & vbCrLf)   
    

    が送信側。

            BTITLE = Request.Form("BTITLE")      
    

    が受信側です。長いデータのやりとりも可能です。

     ◆ <クエリ文字列>や<セッション>を使用する方法

    上の事例ではこのように、Webページ間の情報の受け渡しに<Request.Form コレクション>を使用していますが、この他に<クエリ文字列>や<セッション変数を>を使用する方法もあります。これについては次章でも説明します。

    ●listupdate2aspxの内容(listupdate1.aspxの中から起動されるプログラム)

    <%@ Page ContentType="text/html" Language="VB" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ import Namespace="System.IO" %>
    
    <script runat="server">
        
    Sub UPDATELIST()'------------ 更新
    
            Dim NAME, BTITLE, SYOMEI As String
            Dim strSQLdata As String
            Dim KAISU, NO, sakuzyo, i As Integer
            Dim strRdata(20) As String
    
            SYOMEI = Request.Form("SYOMEI")
            BTITLE = Request.Form("BTITLE")
            NAME = Request.Form("NAME")
            KAISU = Request.Form("KAISU")
            NO = Request.Form("NO")
            sakuzyo = Request.Form("sakuzy")
    
            strSQLdata = "SELECT * FROM SYOLIST"
    
            Dim objDb As New SqlConnection("Server=dwprdb01.dataweb.ne.jp;Database=LIST;UID=TSUKUINOBUAKI;PWD=jsjapan#JS")
            Dim objCom As New SqlCommand(strSQLdata, objDb)
    
            objDb.Open()
            
            Dim DR As SqlDataReader = objCom.ExecuteReader()
     
            If DR.HasRows = True Then   '-- データがある
            Else
                DR.Close()
                objDb.Close()
                Exit Sub
            End If
    
            DR.Close()
    
            If sakuzyo = "ON" Then    '------------------削除
                strSQLdata = "DELETE SYOLIST WHERE [NO]=" & NO
            Else                    '-----------------更新
                strSQLdata = "UPDATE SYOLIST SET [書名]='" & BTITLE & "',[賞名]='" & SYOMEI & "',[著者名]='" & NAME & "',[回数]=" & KAISU & " WHERE [NO]=" & NO
            End If
            
            Dim objCom2 As New SqlCommand(strSQLdata, objDb)
            objCom2.ExecuteNonQuery()
    
            If sakuzyo = "ON" Then       '------------------削除
                Response.Write("<center><dl><li><font color='red'>LIST情報を「削除」しました。</dl></center>")
                Response.Write("<br><center><form><font size='2'><input type='button' value='戻る' onclick='history.back()'><br></font></form></center>")
            Else                        '------------------それ以外は更新
                Response.Write("<center><dl><li><font color='red'>LIST情報を「更新」しました。</dl></center>")
                Response.Write("<br><center><form><font size='2'><input type='button' value='戻る' onclick='history.back()'><br></font></form></center>")
            End If
    
    End sub
    
    </script>
    
    <head>
    <meta http-equiv='content-type' content='text/html; charset=UTF-8' />
    <title>データ修正実行</title>
    </head>
    <body>
    
    <%
        Call UPDATELIST()
    %>
    
    </body>
    </html>
    
    

    データベースに新規データを挿入する

    同様に、データベースに新規データを挿入するためのプログラムです。以下のASPXファイルを実行すると、サーバー内容のテーブル「LIST」の内容を呼び出し、新規の1レコードを挿入します。挿入したデータは更新されます。更新には先ほどと同じ<listupdate2aspx>を使用しています。


     http://www.longview.jp/list/LISTINSERTDATA.aspxx

    <%@ Page ContentType="text/html" Language="VB" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ import Namespace="System.IO" %>
    
    <script runat="Server">
    
        Sub INSERTDATA()
    
            Dim strSQLdata, NAME, BTITLE, SYOMEI As String
            Dim KAISU, NO As Single
            Dim MAXNO As Single
            
            strSQLdata = "SELECT MAX([NO]) AS MAXNO FROM SYOLIST"    '最大値をとる
    
            Dim objDb As New SqlConnection("Server=dwprdb01.dataweb.ne.jp;Database=LIST;UID=TSUKUINOBUAKI;PWD=jsjapan#JS")
            Dim objCom As New SqlCommand(strSQLdata, objDb)
            objDb.Open()
            
            Dim DR2 As SqlDataReader = objCom.ExecuteReader()
    
            While (DR2.Read)
                If DR2.HasRows = False Then   ' データがない
                    Exit Sub
                Else
                    MAXNO = DR2("MAXNO")           '最大値をとり
                    MAXNO = MAXNO + 1           '1増やす
                End If
            End While
    
            DR2.Close()
            objCom.Dispose()
            objDb.Close()
    
            strSQLdata = "INSERT INTO SYOLIST(回数,書名,賞名,著者名,NO) VALUES('','','',''," & MAXNO & ")"
      
            Dim objDb2 As New SqlConnection("Server=dwprdb01.dataweb.ne.jp;Database=LIST;UID=TSUKUINOBUAKI;PWD=jsjapan#JS")
            Dim objCom2 As New SqlCommand(strSQLdata, objDb2)
            objDb2.Open()
              
            objCom2.ExecuteNonQuery()
            objCom2.Dispose()
            objDb2.Close()
    
            strSQLdata = "SELECT * FROM SYOLIST WHERE NO=" & MAXNO
             
            Dim objDb3 As New SqlConnection("Server=dwprdb01.dataweb.ne.jp;Database=LIST;UID=TSUKUINOBUAKI;PWD=jsjapan#JS")
            Dim objCom3 As New SqlCommand(strSQLdata, objDb3)
            objDb3.Open()
    
            Dim DR3 As SqlDataReader = objCom3.ExecuteReader()
    
            While (DR3.Read)
    
                Response.Write("<form method='POST' action='LISTUPDATE2.ASPX' onsubmit='return' name='NSOKFORM'>")
                Response.Write("<table widrh='840' border='1' align='center'>" & vbCrLf)
    
                KAISU = DR3("回数")
                BTITLE = DR3("書名")
                SYOMEI = DR3("賞名")
                NAME = DR3("著者名")
                NO = DR3("NO")
    
                Response.Write("<p>" & vbCrLf)
                Response.Write("<tr><td>")
                Response.Write("<input type='hidden' name='NO' value='" & NO & "'>" & vbCrLf)
                Response.Write("回数:<input type=text name='KAISU' size='60' value='" & KAISU & "'>" & vbCrLf)
                Response.Write("</td></tr><tr><td>")
                Response.Write("書名:<input type=text name='BTITLE' size='60' value='" & BTITLE & "'>" & vbCrLf)
                Response.Write("</td></tr><tr><td>")
                Response.Write("賞名:<input type=text name='SYOMEI' size='60' value='" & SYOMEI & "'>" & vbCrLf)
                Response.Write("</td></tr><tr><td>")
                Response.Write("著者名:<input type=text name='NAME' size='60' value='" & NAME & "'>" & vbCrLf)
                Response.Write("</td></tr><tr><td>")
                Response.Write("</tr></td></table>")
                Response.Write("<center><input type='checkbox' name='SAKUZYO' value='ON'><b>削除</b>(注意)</center>" & vbCrLf)
                Response.Write("<center><input type=submit value=更新></form> [NO:" & NO & "]</center>" & vbCrLf)
                Response.Write("<p>" & vbCrLf)
    
            End While
    
            DR3.Close()
            objCom3.Dispose()
            objDb3.Close()
    
            Response.Write("<center><form><input type='button' value='戻る' onclick='history.back()'></font></form><br>" & vbCrLf)
            Response.Write("<center>更新が可能です。<br></center><br>" & vbCrLf)
    
        End Sub
    
    </script>
    
    <html>
    <head>
    <meta http-equiv='content-type' content='text/html; charset=UTF-8' />
    <meta http-equiv='Content-style-Type' content='text/css' />
    </head>
    <title>新規挿入</title>
    <body>
    
    <%
        Call INSERTDATA()
    %>
    
    </body>
    </html>
    





    ■[8]■ セキュリテイに配慮した運用システムへ

      [目次に戻る]

    運用上の知識


    ●重要なセキュリリティ

    Webシステムを実際に運用するうえで大事なのが「セキュリテイ」です。これは悪意のある誰かが侵入するということもありますが、基本的にインターネットで公開するということは、基本的な技術を持った人ならだれでもそのシステムを見ること、利用することができるという原則があるからです。

    そこで、システムを公開する前に、これは特定多数の人に利用されるものして、そこで情報が漏れたり、データが破壊されたりしないための仕組みが大事になるのです。特に、DBを使って、ユーザーの情報をサーバーに格納したり、ユーザーがこうしたDBデータの閲覧や変更を行えるようになっているシステムについてはよりいっそうの慎重さが必要です。


    ●キュリリティの3段階の要素を以下の3点にまとめてみました

  • パスワードによる利用者の限定・特定
  • ユーザー入力文字列の無害化
  • Eメールアドレスを利用するなど、利用者が特定されるような運用方法の採用
  • パスワードを設定して、データの変更システムを保護する

     「パスワードの設定」ではページ間の情報の受け渡しに注意する

    先に述べたように、Webページ間の情報の受け渡しに通常は<form>を使用していますが、セキュリテイの高い情報のやり取りには暗号化した<クエリ文字列>や<セッション変数を>を使用する方法のほうがいいと思います。

     ◆ Webページ間の情報の受け渡しに<QueryString>を使用する

    <クエリ文字列>データは QueryString コレクションに入れられて、受け取ほうのWebページは、<HttpRequest オブジェクトのQueryString>プロパティからクエリ文字列の値を読み取ります。ただし、<クエリ文字列>はあまり長い文字列は指定できませんので、使用法は限定されます。また、この文字列を暗号化することによって、ある程度のセキュリテイを確保できます。

     http://www.jswork.jp/dg/jsDBdatasearch.aspx?NO=24  
    

    が送信側。通常はこのようにURLに?のあとで追加します。

     BOOKNO=request.querystring("NO")  
    

    が受信側です。

     ◆ Webページ間の情報の受け渡しに<セッション>を使用する方法

    以上の2つの方法は受け渡すデータをHTMLデータやURLなどに記述しますので、ユーザーは、送信される内容を知ることができます。通常は問題ありませんが、なにがしかのセキュリティ上の問題などでこうした方法が使えない場合に<セッション変数を>を利用するという方法があります。これはASP.NETの実行環境であるIIS独自の機能で、変数はサーバーのメモリに共通変数しておかれますので、使い方により非常に有効です。

     Session("USER") = Me.TextBox1.Text  
    

    が送信側。

     USER = Session("USER")  
    

    が受信側です。セッション変数には有効時間が設定されていて、基本は20分を過ぎると無効になります。つまり、更新の画面を開いても20分間なにもしなければ更新作業はできなくなるという設定を組み込むことができます。また、セッションはパソコン単位で、しかもブラウザを閉じてしまえば無効になります。これもセキュリティの向上につながります。

    パスワードを設定するフォームの作成

    前回で、DBへのデータの登録と変更、削除のプログラムを作成しました。しかし、実際には、こうしたプログラムを利用するのは特定の利用者に限定するのが普通です。たとえば、ある団体の名簿であれば、閲覧はできるが、変更・削除・新規追加は「管理者」としての権限をもったユーザーだけにするなどのケースがあります。

    こうした場合、通常は、最初に「パスワード」など管理者しか知りえない情報を設定して、それを入力した場合にだけ、次の作業に進むという方法をとります。以下の事例(フォーム)はその「パスワード」入力を求め、その結果を次のプログラムに送信します。

    これは最初に以下のような入力フォームを経由して、利用者を特定する方法で、非常に多くのサイトで使われている方法です。

    ASPNET_OpenPsw.aspx ・パスワードフォーム事例:http://www.longview.jp/list/ASPNET_OpenPsw.aspx

    このプログラムのソースコードは以下のようになります。拡張コントロールを使用しているので先ほどとは少し違うと思います。また、セッションを利用してパスワードをユーザーの目に触れない形で転送しています。

    <%@ Page ContentType="text/html" Language="VB" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ import Namespace="System.IO" %>
    
    <script runat="Server">
    
        Dim objDr As SqlDataReader
        Dim BookNO As Integer
        Dim strDATA As String
        Dim strSQLdata As String
        Dim strOUTtext As String
        Dim strAteaki As String
        
        Sub objBtn2_Click(ByVal sender As Object, ByVal e As EventArgs)
            Response.Redirect("http://www.jsjapan.net/index.html")
        End Sub
        
        Protected Sub Button3_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        End Sub
        Sub objBtn1_Click(ByVal sender As Object, ByVal e As EventArgs)
            
            If Me.TextBox1.Text = "1234" Then   'パスワードのチェック
    	        Session("USER") = Me.TextBox1.Text
            	If objchk1.Checked Then
                    Server.Transfer("OpenLIST.ASPX")
                ElseIf objchk2.Checked Then
                    Server.Transfer("LISTINSERTDATA.ASPX")
                ElseIf objchk3.Checked Then
                    Server.Transfer("LISTUPDATE1.ASPX")
                End If
            Else
    			Response.Redirect("nothing.aspx")	'←ない場合に表示
            	 Exit Sub
            End If
            
        End Sub
    
    </script>
    
    <html>
    <head>
    <title>テーブルのデータ出力・変更画面</title>
    <script language="JavaScript">
    <!--
    <asp:Literal id="objLtr" runat="Server" />
    //-->
    </script>
    
        </head>
    <body>
    
    <form runat="server">
    
    <%       
     %>
    <table id="Table1" cellpadding="0" cellspacing="0" border="1" bgcolor="#FFE0C9" height="1" width="800" align='center'><tr><td style="height: 229px">
    <br />
    <center>
        パスワードを入力して「開始」ボタンを押してください</center>
      <br />
       <table id="Table2" cellpadding="0" cellspacing="0" border="1" bgcolor="#FFE0C0" height="1" width="740" align='center'><tr><td style="height: 121px">
    <br />
      <asp:RadioButton ID="objchk1" runat="server" Text="リストの表示"  TextAlign="Right" GroupName="RegularMenu"  Checked="True" Height="18px" Width="402px" ForeColor="Black"
    />  <br />
    <br />
      <asp:RadioButton ID="objchk2" runat="server" Text="新規リストの追加" TextAlign="Right" GroupName="RegularMenu"  Checked="false"  Height="16px" Width="480px" ForeColor="Black"
    />
    <br />
    <br />
      <asp:RadioButton ID="objchk3" runat="server" Text="リストの更新" TextAlign="Right" GroupName="RegularMenu"  Checked="false"  Height="16px" Width="480px" ForeColor="Black"
    />
    <br /><br /><br />
           <center>パスワード: <asp:TextBox TextMode="Password" ID="TextBox1" runat="server" Width="150px"></asp:TextBox></center>
    <br />
            <asp:label runat="server" id="lbl1" />
    <br />
            <center> <asp:Button id="Button1" runat="Server" Text="開始" OnClick="objBtn1_Click" Width="251px"  /></center>
    <br />
    </td></tr></table>
        <br />
    <center>
        <asp:Button id="Button2" runat="Server" Text="中止(自費出版ネットワークホームページへ)" 
            OnClick="objBtn2_Click" Width="379px"  />
    <br />
    </center>
    
          <asp:Literal ID="Literal1" runat="server"></asp:Literal>
        
    </td></tr></table>
    </form>
    
    </body>
    </html>
    

    この開発環境は実際には以下のようにコードと実際のフォームオブジェクトを並行して確認できるようになります。これは先に述べたように<Visual Web Developer 2010 Express>を使用しています。




    「保護ディレクトリ」の利用

    これは、Webサイトの機能ですが、特定のパスワードでしか入れない「保護ディレクトリ」を利用できることがあります。この接続機能を使って、そこに置いたファイルを許可されたユーザーだけに表示されるようにすることができます。この機能は利用するレンタルサーバーのオプション機能ですので、必要な場合には事前に確認することが必要です。

    ・「保護ディレクトリ」の例:http://www.jswork.jp/jsmember/

    ユーザー入力文字列の無害化

    ユーザーがデータを入力し、その結果をDBなどの検索や処理に使用するページの場合、入力された文字列に悪意のあるデータが挿入されることがあります(このような事例を「SQLインジェクション=スクリプトによる攻略」といいます)。それを防ぐ方法が必ず必要です。

    ASP.NET 規定の動作では、入力にHTMLタグ(例えば<body>)が含まれていると、エラーになるように作られているので(バリデーション処理)、かつてのように「<script></script>」などのタグを書き込まれる恐れはなくなっていますが、それでも注意は絶対に必要です。

    ・以下の説明をご覧ください:

    ・事例説明1:スクリプトによる攻略の概要

    ・事例説明2:[SQLインジェクション攻撃の説明]

    実際には以下のように入力文字列について危険な文字を削除する方法をとります。

      strRdata(1) = "'"
      strRdata(2) = ";"
      strRdata(3) = "/*"
      strRdata(4) = "/*"
      strRdata(5) = "_"
      strRdata(6) = ".."
      strRdata(7) = "--"
      strRdata(8) = ","
      strRdata(9) = "\"
      strRdata(10) = "<"
     
     For i = 1 To 10   '危険な文字を削除
    	DATAE01 = Replace(DATAE01, strRdata(i), "") '全角にするなどほかの方法もある
     Next
    

    コードとプログラムを分けた開発方法を利用する

    前の章でも触れましたが、ASP.NETの開発には、Visual Web Developer 2010 Expressという専用の開発ツールがあります。これは「Visual Studio (Visual Web Developer)」という総合開発環境の一部です。従来のASP(レガシーASPといいます。私もこれで作成し、あとからASP.NET 2.0=ASPXに変換しました)では、サーバー側で処理するプログラム コードを HTML のソース中に挿入するインライン コード モデルで記述します。それに対し、ASP.NET 2.0 では、インライン コード モデルの他に、コード ビハインド モデルによる記述方法がサポートされています。コード ビハインド モデルでは、ページのデザインとプログラム コードを分離して記述することができます。

    この開発環境では、<ポストバック>という概念が使われています。「runat="server"」の付いたタグ内では、ポストバックの仕組みによりポストしたデータを処理するのは、常にそのページ自身となります。そのため、ASP.NETのページには基本的に入力フォーム部分と処理結果の表示部分が存在します。「runat="server"」が指定されたエレメントだけがASP.NETエンジンの処理対象になります。

     開発環境事例 web-developer-2010-express

    実際にはセキュリティの問題などで、このような拡張コントロールを使用した方がいい場合もあります。私もテキストエディタを基本としながらも、この「Visual Web Developer 2010 Express」での編集を併用します。こうすると、コードとフォームなどのコントロールを分けた開発が可能になり、されに通常のVBなどの開発のようにイベント制御でプログラムを扱うこともできます(旧来の処理では処理単位にプログラを分離させることになります)。また、HTMLタグの確認や変数管理、VBのエラーチェック機能などが便利に利用できます。ただ、ほんの少しの修正で立ち上がるまでの時間がかかり、ややうっとうしいこともあります。

    エラー処理

    ASPXは最初の実行時にサーバー上のIISにより文書構造などがチェックされ、中間言語にコンパイルされます。そのチェックでエラーが出ると処理が中断します。この場合、デバッグに必要なのでエラー箇所を画面に表示するように設定できます。しかし、エラーの表示は通常の場合にはコードの中味を外部に表示することになりますから避けなければなりません。
    そこで、ASPXの開発や修正にあたっては以下のような手順をとります。

    1. 修正したいASPXをローカルで保存する。
    2. サーバー上の同じ名前のASPXを別名(例
    3. abc.aspx→abc-old.aspxなど)に変更=失敗したとき元に戻せるようにするため。
    4. 同じディレクトリにある「web.config」の記述を一部変更し、、サーバに上書き転送する
    5.  <customErrors defaultRedirect="customError.html" mode="On"/> ←Offに変更
    6. 修正したASPXをローカルからサーバに転送。
    7. ASPXを実行する。
    8. 失敗の場合、エラーの内容を見て、ASPXを再修正し、4に戻る。
    9. 成功した場合は、「web.config」の記述を元に戻し(On)、サーバに上書き転送する。
    10. サーバー上の(abc-old.aspxなど)別名ファイルを削除する。

     * 特に8を忘れないこと。
     * 4で、エラーを表示しない場合(mode="On")には、あらかじめ設定しておいた<customError.html>が表示されます。
     * サーバーのルート上にあるweb.configは全体のシステム設定用でユーザーは操作しません。3で使用するのはあくまで、各ディレクトリにあるweb.configですので気をつけてください。






    ■[9]■ SQL文の実際

      [目次に戻る]

    ・テーブルの作成に関するSQLコマンド

    テーブルの作成や定義、変更は、Webシステムでの対話によってもできますが、ネット経由の操作はいかにも歯がゆいところがあります。そこで、なるべくなら、SQLコマンドを使用しての作業を行います。SQLサーバーの場合は「Transact-SQL」という一部独自に拡張したSQL言語を使用します。 以下に主要な命令を実例で表示します。

    ・テーブルの作成

    CREATE TABLE [dbo].[名簿](
    	[id] [int] IDENTITY(1,1) NOT NULL,
    	[氏名] [nvarchar](50) NULL,
    	[電話] [nvarchar](50) NULL,
    	[Eメール] [nvarchar](50) NULL,
    	[年齢] [int] NULL,
    	[備考] [varchar](200) NULL,
     CONSTRAINT [PK__名簿] PRIMARY KEY CLUSTERED 
    (
    	[id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    

    ・テーブル名の変更

    sp_rename 'oldname', 'newname'
    sp_rename '友の会会員名簿','名簿_2'
    

    ・テーブル列名の変更

    p_rename '名簿2.氏名', '姓名', 'COLUMN'
    

    ・コラムの定義変更

    ALTER TABLE [名簿] column_definition IDENTITY(ID)
    GO
    

    ・テーブル列の追加

    ALTER TABLE [JSDATAALL] ADD [REGTYPE] int
    ALTER TABLE [TABLENAME] ADD CITYCODE int
    ALTER TABLE [TABLENAME] ADD [項目名] nvarchar(20)
    ALTER TABLE [TABLENAME] ADD [998] float DEFAULT 0"
    

    ・テーブル列の削除

    ALTER TABLE [TABLENAME] DROP COLUMN [コラム名]

    ・テーブルの削除

    drop table sak.品番m
    

    データを選択する

    SELECT * FROM [JSDATAALL]
    

    データの更新

    ・テーブルデータの変更

    条件がEBOOKNO=9999であるデータ行の項目[SHOW]を変更する
     UPDATE [jsebooklist] SET [SHOW]='ON' WHERE EBOOKNO=9999
    対象のTABLEの項目を別のTABLEの値を比較して更新する
     UPDATE [jsebooklist] SET [A]=登録保存.[B] FROM 登録保存 WHERE [jsebooklist].[ID]=[登録保存].[ID]
    計算する
     UPDATE [jsebooklist] SET [税込定価]=([定価] * 0.08)+[定価]
    テーブルAの[コース]のデータを「-」までの文字に変換
     UPDATE A SET [コース]=SUBSTRING([コース],1,CHARINDEX('-',[コース)-1) WHERE CHARINDEX('-',[コース])>1 
    

    [著者] 筑井信明(Tsukui Nobuaki)
    株式会社エヌケイ情報システム/自費出版ネットワーク理事 [連絡はこちら]


     [目次に戻る]