先の記事 コレクションのデータアノテーション検証 でユーザー入力の検証の話を書きましたが、デフォルトで有効になっているクライアント側での検証を無効にするにはどうすればいいかという話を書きます。
これは、Visual Studio 2010 で MVC4 アプリを インターネットアプリケーション テンプレートで作った場合の話で、Visual Studio 2013 とか MVC5 とかでは違うかもしれませんのでご注意ください。
アプリケーションルート直下の web.config での以下の定義がされており、クライアント側での検証がアプリケーション全体で有効に設定されています。
<appSettings>
・・・中略・・・
<add key="ClientValidationEnabled" value="true" />
・・・中略・・・
</appSettings>
クライアント側での検証を無効にしたいことがあるとすると多分特定の View だけでしょうから、その場合は当該 View のコードに下記を追加すれば OK です。
@{
Html.EnableClientValidation(false);
}
クライアント側検証には EnableClientValidation の他に EnableUnobtrusiveJavaScript が使われていますが、stackoverflow の記事 によると、後者は Ajax にも使われていて、false にすると Ajax が動かなくなるとのことなので注意してください。
以上で話は終わりなのですが、それだけでは記事としてはちょっと面白くないので、上記に関連して調べたことを備忘録として書いておきます。(笑)
MVC4 の新機能として JavaScript / CSS ファイルの縮小化と結合処置の自動化機能があり、その機能を利用するため、App_Start フォルダの BundleConfig.cs ファイルに以下の定義がされています。
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
"~/Scripts/jquery-ui-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
// ・・・中略・・・
}
}
アプリケーションルート直下の Scripts フォルダには jquery-1.7.1.js, jquery.validate.js その他必要な jQuery 関係の外部スクリプトファイルが自動的に配置されます。
Global.asax には以下のコードが記述されており、アプリケーション起動時に外部スクリプトファイルのパスが ASP.NET の BundleCollection オブジェクトに登録されるようになっています。(詳しくは @IT の記事 Visual Studio 2012の新機能とASP.NET 4.5のコア機能 (3/4) を見てください)
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// ・・・中略・・・
BundleConfig.RegisterBundles(BundleTable.Bundles);
// ・・・中略・・・
}
}
BundleCollection オブジェクトに登録した外部スクリプトファイルを参照するには、View で Scripts.Render メソッド を使用します。
具体的には _Layout.cshtml(Web Forms アプリのマスターページに相当)の @Scripts.Render("~/bundles/jquery") と View の @Scripts.Render("~/bundles/jqueryval") で以下の外部スクリプトファイルへの参照が HTML ソースに定義されます。
<script src="/Scripts/jquery-1.7.1.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
(注)上記は <compilation debug="true" ... /> の場合です。debug="false" の場合はファイルの縮小化と結合処置の自動化機能が働いて以下のようになります。
<script src="/bundles/jquery?v=1A_Q..."></script>
<script src="/bundles/jqueryval?v=-tc2Q..."></script>
以上ような設定において、例えば Model にアノテーション属性を以下のように付与したとします。
public class Parent
{
//・・・中略・・・
[Required(ErrorMessage = "{0} は必須")]
[StringLength(5, ErrorMessage = "{0} は {1} 文字以内")]
[Display(Name = "Parent Name")]
public string Name { get; set; }
//・・・中略・・・
}
そして、View のコードを以下のように記述したとします。
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
そうすると、クライアント側検証が有効の場合(Html.EnableClientValidation(true) の時)は、ASP.NET がレンダリングする HTML ソースは以下のようになります。
<div class="editor-label">
<label for="Name">Parent Name</label>
</div>
<div class="editor-field">
<input
class="text-box single-line"
data-val="true"
data-val-length="Parent Name は 5 文字以内"
data-val-length-max="5"
data-val-required="Parent Name は必須"
id="Name"
name="Name"
type="text"
value="" />
<span
class="field-validation-valid"
data-valmsg-for="Name"
data-valmsg-replace="true">
</span>
</div>
上記のように input 要素に付与された data-val* 属性に従って、参照された外部スクリプトに含まれる Unobtrusive(控えめな)JavaScript がクライアント側での検証を行うようになります。
一方、クライアント側検証を無効にした場合(Html.EnableClientValidation(false) の時)は ASP.NET がレンダリングする HTML ソースは以下のようになります。(注:外部スクリプトファイルへの参照は変わりません)
<div class="editor-label">
<label for="Name">Parent Name</label>
</div>
<div class="editor-field">
<input
class="text-box single-line"
id="Name"
name="Name"
type="text"
value="" />
</div>
クライアント側での検証はかかりませんがサーバー側で検証は行われ、検証結果が NG の場合は input 要素の直後に以下の span 要素が追加され、エラーメッセージ(上の画像の赤い文字)が表示されます。
<span class="field-validation-error">
Parent Name は必須
</span>