独自のデータ検証を行う
* 以下の2パターンを考える [1] 1つのプロパティに対して、独自の検証を行う [2] 複数プロパティをまたがった検証を行う ※今回は、[1]を扱う
■ポイント
=> ValidationAttributeを継承することにより、カスタム属性の作成する ※ただ、正規表現による検証「RegularExpressionValidator」を使用できないかを検討してみた方がいいhttp://blog.shibayan.jp/entry/20110708/1310132392
http://blog.shibayan.jp/entry/20130619/1371576352
http://www.atmarkit.co.jp/fdotnet/scottgublog/20100208mvc2mvalidation/mvc2mvalidation.html
http://www.remember-the-time.xyz/2012/05/aspnet-mvc-url.html
http://d.hatena.ne.jp/fyts/20071017/validator
クライアント側でのチェックをするための環境設定
環境
* Visual Studio : Microsoft Visual Studio Express 2015 for Web
手順
[1] Visual Studio で [ツール]-[NuGetパッケージ マネージャー]-[パッケージ マネージャー コンソール]を選択 [2] 以下のコマンド(2つ)を入力する Install-Package jQuery.Validation Install-Package jQuery.Validation.Unobtrusivehttps://www.nuget.org/packages/jQuery.Validation/
https://www.nuget.org/packages/jQuery.Validation.Unobtrusive/
出力画面:パッケージ マネージャー コンソール
パッケージ マネージャー コンソール ホストのバージョン 3.0.0.0 利用可能なすべての NuGet コマンドを参照するには、'get-help NuGet' を入力します。 PM> Install-Package jQuery.Validation '.NETFramework,Version=v4.6' を対象とするプロジェクト 'WebAppli' に関して、パッケージ 'jQuery.Validation.1.14.0' の依存関係情報の収集を試行しています DependencyBehavior 'Lowest' でパッケージ 'jQuery.Validation.1.14.0' の依存関係の解決を試行しています パッケージ 'jQuery.Validation.1.14.0' をインストールするアクションを解決しています パッケージ 'jQuery.Validation.1.14.0' をインストールするアクションが解決されました パッケージ 'jQuery.Validation.1.14.0' をフォルダー 'C:\Xxxx\visual studio 2015\Projects\WebAppli\packages' に追加しています パッケージ 'jQuery.Validation.1.14.0' をフォルダー 'C:\Xxxx\visual studio 2015\Projects\WebAppli\packages' に追加しました パッケージ 'jQuery.Validation.1.14.0' を 'packages.config' に追加しました 'jQuery.Validation 1.14.0' が WebAppli に正常にインストールされました PM> Install-Package jQuery.Validation.Unobtrusive '.NETFramework,Version=v4.6' を対象とするプロジェクト 'WebAppli' に関して、パッケージ 'jQuery.Validation.Unobtrusive.2.0.20710' の依存関係情報の収集を試行しています DependencyBehavior 'Lowest' でパッケージ 'jQuery.Validation.Unobtrusive.2.0.20710' の依存関係の解決を試行しています パッケージ 'jQuery.Validation.Unobtrusive.2.0.20710' をインストールするアクションを解決しています パッケージ 'jQuery.Validation.Unobtrusive.2.0.20710' をインストールするアクションが解決されました パッケージ 'Microsoft.jQuery.Unobtrusive.Validation.2.0.20710' をフォルダー 'C:\Xxxx\visual studio 2015\Projects\WebAppli\packages' に追加しています パッケージ 'Microsoft.jQuery.Unobtrusive.Validation.2.0.20710' をフォルダー 'C:\Xxxx\visual studio 2015\Projects\WebAppli\packages' に追加しました パッケージ 'Microsoft.jQuery.Unobtrusive.Validation.2.0.20710' を 'packages.config' に追加しました 'Microsoft.jQuery.Unobtrusive.Validation 2.0.20710' が WebAppli に正常にインストールされました 依存関係のみが含まれるパッケージ 'jQuery.Validation.Unobtrusive.2.0.20710' をプロジェクト 'WebAppli' に追加しています。 パッケージ 'jQuery.Validation.Unobtrusive.2.0.20710' をフォルダー 'C:\Xxxx\visual studio 2015\Projects\WebAppli\packages' に追加しています パッケージ 'jQuery.Validation.Unobtrusive.2.0.20710' をフォルダー 'C:\Xxxx\visual studio 2015\Projects\WebAppli\packages' に追加しました パッケージ 'jQuery.Validation.Unobtrusive.2.0.20710' を 'packages.config' に追加しました 'jQuery.Validation.Unobtrusive 2.0.20710' が WebAppli に正常にインストールされました PM>
サンプル
http://blogs.yahoo.co.jp/dk521123/35593993.htmlのサンプルに、独自検証(サーバ側、クライアント側)を行う # コントローラ「PersonController.vb」およびビュー「Result.vbhtml」に変更はないので省略。
■ カスタム属性
* NoneValidationAttribute.vbImports System.ComponentModel.DataAnnotations Imports System.Globalization Imports System.Web.Mvc <AttributeUsage(AttributeTargets.Property, AllowMultiple:=False)> Public Class NoneValidationAttribute : Inherits ValidationAttribute Implements IClientValidatable ' 値リストを表すプライベート変数 Private _opts As String Public Sub New(ByVal opts As String) Me._opts = opts Me.ErrorMessage = "{0}は、{1}を設定しないで下さい。" End Sub ' プロパティの表示名と値リストでエラー・メッセージを整形 Public Overrides Function FormatErrorMessage(ByVal name As String) As String Return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, Me._opts) End Function Public Function GetClientValidationRules( metadata As ModelMetadata, context As ControllerContext) As IEnumerable(Of ModelClientValidationRule) Implements IClientValidatable.GetClientValidationRules ' 検証ルールを準備 Dim rule = New ModelClientValidationRule() With { .ValidationType = "enumnonevalue", ' 検証名 .ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()) ' エラー } rule.ValidationParameters("opts") = Me._opts ' 検証パラメータ Dim list = New List(Of ModelClientValidationRule)() list.Add(rule) Return list End Function ' サーバ側の検証 Public Overrides Function IsValid(ByVal value As Object) As Boolean ' 入力値が空の場合は検証をスキップ If value Is Nothing Then Return True End If ' Noneだったら不正 If value.ToString().Equals("None") Then Return False End If Return True End Function End Class
■ モデル
* PersonModel.vbImports System.Web.Mvc Namespace Models Public Class PersonModel Private Property _Id As Long Private Property _Name As String Private Property _Gender As Gender <ComponentModel.DisplayName("ID")> <ComponentModel.DataAnnotations.Required(ErrorMessage:="{0}は必須です。")> <ComponentModel.DataAnnotations.Range(100, 10000, ErrorMessage:="{0}は{1}~{2}の間で入力してください。")> Public Property Id As Long Get Return Me._Id End Get Set(ByVal value As Long) Me._Id = value End Set End Property <ComponentModel.DisplayName("名前")> <ComponentModel.DataAnnotations.Required(ErrorMessage:="{0}は必須です。")> <ComponentModel.DataAnnotations.StringLength(100, ErrorMessage:="{0}は{1}文字以内で入力してください。")> Public Property Name As String Get Return Me._Name End Get Set(ByVal value As String) Me._Name = value End Set End Property ' ★ここに適用★ <NoneValidation("None")> Public Property Gender As Gender Get Return Me._Gender End Get Set(ByVal value As Gender) Me._Gender = value End Set End Property End Class Public Enum Gender None Man Woman End Enum End Namespace
■ ビュー
* Index.vbhtml@ModelType WebAppli.Models.PersonModel @Code ViewData("Title") = "View" End Code <script src="@Url.Content("~/Scripts/jquery-1.10.2.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/enumNoneValue.js")" type="text/javascript"></script> <h2>View</h2> @Using (Html.BeginForm( "Result", ' アクション名 "Person", ' コントローラ名 FormMethod.Post)) @Html.AntiForgeryToken() @Html.ValidationSummary(False, "", New With {.class = "text-danger"}) @Html.LabelFor(Function(model) model.Id, htmlAttributes:=New With {.class = "control-label col-md-2"}) @Html.EditorFor(Function(model) model.Id, New With {.htmlAttributes = New With {.class = "form-control"}}) @Html.ValidationMessageFor(Function(model) model.Id, "*") @<br /> @Html.LabelFor(Function(model) model.Name, htmlAttributes:=New With {.class = "control-label col-md-2"}) @Html.EditorFor(Function(model) model.Name, New With {.htmlAttributes = New With {.class = "form-control"}}) @Html.ValidationMessageFor(Function(model) model.Name, "*") @<br /> @Html.EnumDropDownListFor(Function(model) model.Gender, "Please select", Nothing) @Html.ValidationMessageFor(Function(model) model.Gender, "*") @<br /> @<input type = "submit" value="Send" Class="btn btn-default" /> End Using
■ JavaScript:クライアント側の検証
* /Scripts/enumNoneValue.js// インテリセンス機能を有効化 /// <reference path="jquery-1.10.2.js" /> // enumNoneValue検証をjQuery Validationに登録 $.validator.addMethod("enumnonevalue", function (value, element, param) { // 入力値が空の場合は検証をスキップ value = $.trim(value); if (value === '') { return true; } // Noneだったら不正 if (value === "0") { return false; } return true; }); $.validator.unobtrusive.adapters.addSingleVal('enumnonevalue', 'opts');
参考文献
[1] 1つのプロパティに対して、独自の検証を行うhttp://cs.gogo-asp.net/blogs/naoki/archive/2010/07/02/ASP.NET-MVC-2-_6730AB30B930BF30E0305E5C27606E305C4F106268300130AF30E930A430A230F330C830B530A430C9301C693C8A6E30DD30A430F330C830_.aspx
* サーバ側
http://www.atmarkit.co.jp/fdotnet/aspnetmvc3/aspnetmvc3_05/aspnetmvc3_05_01.html
* クライアント側
http://www.atmarkit.co.jp/fdotnet/aspnetmvc3/aspnetmvc3_05/aspnetmvc3_05_02.html
http://blog.shibayan.jp/entry/20110108/1294423577