Try~Catch文を使ってエラー処理を追加したプログラム
今回は、ログイン画面を作成して、Try~Catch文を使ったエラー処理を追加します。
ログイン画面のイメージは、以下のようになります。
Try~Catch文に関する内容は、以下のマイクロソフトの公式サイトを参照してください。
新規プロジェクトの作成
新規にプロジェクトを作成します。
今回のサンプルプログラムでは、プロジェクト名を「Test7」として作成します。
プロジェクトの作成方法は、こちらの記事を参照してください。
データベースの作成
今回のプロジェクトで使用するデータベースを作成します。
データベースは、Visual Studio付属の「SQL Server Express LocalDB」を使用します。
データベースの作成方法は、こちらの記事を参照してください。
データベースの仕様は、以下の通りです。
IDをプライマリーキーとして、1001から始まる自動採番とします。
データベースの仕様
- データベース名:TestDb
- テーブル名:Account
名前 | データ型 | Nullを許容 | その他 |
---|---|---|---|
ID | int | NOT NULL | IDENTITY (1001, 1) |
Name | nvarchar(20) | NOT NULL | |
Password | varchar(20) | NOT NULL |
Accountテーブルのデータも、あらかじめインサートしておきます。
メニューバーの「ツール」→「SQL Server」→「新しいクエリ」で、クエリ画面から以下のSQL文を使ってデータをインサートします。
データ
insert into Account values(N'山田太郎','password1234');
insert into Account values(N'鈴木花子','password5678');
ADO.NET Entity Data Modelの作成
データベースを作成したら、VB.NETとデータベースを接続するために、ADO.NET Entity Data Modelを作成します。
モデル名は、「TestDbModel」とします。
ADO.NET Entity Data Modelの作成方法は、こちらの記事を参照してください。
Accountクラスにアノテーションを追加
自動で作成されたAccountクラスの各プロパティに、アノテーションを追加します。
ログイン画面で入力するIDとパスワードは必須項目なので、Required()を指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Imports System Imports System.Collections.Generic Imports System.ComponentModel Imports System.ComponentModel.DataAnnotations Partial Public Class Account <DisplayName("ID")> <Required(ErrorMessage:="{0}を入力してください")> Public Property Id As Integer <DisplayName("氏名")> Public Property Name As String <DisplayName("パスワード")> <Required(ErrorMessage:="{0}を入力してください")> Public Property Password As String End Class |
データベース操作用クラスの作成
データベースを操作するためのクラスを、「DbModel.vb」という名前で、「Data」フォルダーの配下に作成します。
「Data」フォルダーは、あらかじめ作成しておきます。
検索結果は0件か1件になるので、SQLQuery()メソッドにFirstOrDefault()メソッドを指定します。
FirstOrDefault()メソッドの代わりにFirst()メソッドを使った場合は、検索結果が0件だと例外が発生します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Public Class DbModel Function GetAccount(id As Integer, password As String) As Account Dim account As Account Dim sql As String = $" SELECT Id, Name, Password FROM Account WHERE Id={id} and Password='{password}'; " Using db As New TestDbEntities account = db.Database.SqlQuery(Of Account)(sql).FirstOrDefault() End Using Return account End Function End Class |
ログイン画面用コントローラーの作成
ログイン画面用のコントローラーを作成します。
Try~Catch文を使って、エラー処理を実装します。
Tryブロックの中で例外が発生すると、Catchブロックの処理を実行します。
Catchブロックの中でErrorコントローラーのSystemメソッドを呼び出します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
Imports System.Web.Mvc Namespace Controllers Public Class LoginController Inherits Controller <HttpGet()> Function Login() As ActionResult Return View() End Function <HttpPost()> Function Login(vm As Account) As ActionResult If Not ModelState.IsValid Then Return View(vm) End If Try Dim model As New DbModel Dim data As Account = model.GetAccount(vm.Id, vm.Password) '該当なし If IsNothing(data) Then ViewData("ErrMsg") = "IDまたはパスワードが違います" Return View(vm) Else TempData("Value") = data Return RedirectToAction("MyPage", "Home") End If Catch ex As Exception Return RedirectToAction("System", "Error") End Try End Function End Class End Namespace |
ログイン画面用ビューの作成
ログイン画面用のビューを作成します。
HTMLヘルパーのValidationMessageFor()メソッドを使って、未入力だった場合の処理を行います。
未入力時の処理に関しては、こちらの記事も参照してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
@ModelType Account @Code ViewData("Title") = "Login" End Code <div class="login"> <div class="label"> <p>@Html.LabelFor(Function(model) model.Id):</p> <p>@Html.LabelFor(Function(model) model.Password):</p> </div> <div class="input-box"> @Using Html.BeginForm("Login", "Login", FormMethod.Post) @<p> @Html.TextBoxFor(Function(model) model.Id, New With {.maxlength = "20"}) @Html.ValidationMessageFor(Function(model) model.Id) </p> @<p> @Html.PasswordFor(Function(model) model.Password, New With {.maxlength = "20"}) @Html.ValidationMessageFor(Function(model) model.Password) </p> @<input type="submit" value="ログイン" /> End Using <div class="err-msg">@ViewData("ErrMsg")</div> </div> </div> |
表示レイアウトの編集
ビューを作成すると、自動的に「Views/Shared/_Layout.vbhtml」が作成されるので、これを以下のように編集します。
1 2 3 4 5 6 7 8 9 10 11 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8" /> <title>@ViewBag.Title - My ASP.NET Application</title> <link href="~/Content/Site.css" rel="stylesheet" type="text/css" /> </head> <body> @RenderBody() </body> </html> |
ログイン完了画面用コントローラーの作成
ログイン完了画面用のコントローラーを作成します。
1 2 3 4 5 6 7 8 9 10 11 |
Imports System.Web.Mvc Namespace Controllers Public Class HomeController Inherits Controller Function MyPage() As ActionResult Return View() End Function End Class End Namespace |
ログイン完了画面用ビューの作成
ログイン完了画面用のビューを作成します。
1 2 3 4 5 6 7 8 |
@ModelType Account @Code ViewData("Title") = "MyPage" End Code <h2>ログイン完了</h2> <p>@Html.LabelFor(Function(model) model.Id):@TempData("Value").Id</p> <p>@Html.LabelFor(Function(model) model.Name):@TempData("Value").Name</p> |
エラー画面用コントローラーの作成
Tryブロックの中で例外が発生した時に呼び出されるコントローラーを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 |
Imports System.Web.Mvc Namespace Controllers Public Class ErrorController Inherits Controller 'システムエラー Function System() As ActionResult Return View() End Function End Class End Namespace |
エラー画面用ビューの作成
Tryブロックの中で例外が発生した時に呼び出されるビューを作成します。
1 2 3 4 5 |
@Code ViewData("Title") = "System" End Code <h2 class="err-msg">!!! システムエラーが発生しました !!!</h2> |
スタイルシートの修正
このプロジェクトで使用するスタイルシート(Site.css)を修正します。
field-validation-errorクラスとinput-validation-errorクラスは、HTMLヘルパーのValidationMessageFor()メソッドで使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
body { margin: 10px; padding: 10px; } .login { height: 200px; width: 700px; margin: 50px auto 0; overflow: hidden; } .label { width: 30%; text-align: right; float: left; } .input-box { width: 70%; float: left; } .err-msg { color: red; margin-top: 20px; } /* エラーメッセージ色設定(HTMLヘルパー用) */ .field-validation-error { color: red; } /* ボックス色設定(HTMLヘルパー用) */ .input-validation-error { background-color: lightpink; } |
RouteConfigの修正
RouteConfig.vbを修正して、ルートページをログイン画面になるように変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Web Imports System.Web.Mvc Imports System.Web.Routing Public Module RouteConfig Public Sub RegisterRoutes(ByVal routes As RouteCollection) routes.IgnoreRoute("{resource}.axd/{*pathInfo}") routes.MapRoute( name:="Default", url:="{controller}/{action}/{id}", defaults:=New With {.controller = "Login", .action = "Login", .id = UrlParameter.Optional} ) End Sub End Module |
プログラムの実行
以下に、画面の表示パターンを提示します。
必須項目未入力
ログイン画面で必須項目が未入力だった場合は、以下のようにテキストボックスの色がピンクになり、テキストボックスの横にエラーメッセージが表示されます。
IDまたはパスワード相違
IDまたはパスワードが間違っている場合は、以下のようにログインボタンの下に、エラーメッセージが表示されます。
例外発生
Try~Catch文で例外が発生した場合は、以下の画面が表示されます。
例外の出し方はいくつかありますが、今回はDbModelクラスの13行目を、FirstOrDefault()からFirst()に変更して実行し、ログイン画面で存在しないID、パスワードを入力することによって、例外を発生させています。
正常画面
正常にログインした場合は、以下の画面が表示されます。