ASP.NET CoreとjQuery Validationを組み合わせた忘備録。
環境
Visual Studio 2017(2015でも同じですが…)
☆ASP.NET Core 1.1
★bootstrap 3.3.7
★jQuery 3.2.1
★jQuery Validation 1.14.0
★jQuery Validation Unobtrusive 3.2.6
☆NuGetからインストール(あるいは標準でインストールされているもの)
★Bowerからインストール(あるいは標準でインストールされているもの)
※基本、以下コード例はVisual Studio -> 新規プロジェクト作成 -> 「ASP.NET Core Web アプリケーション(.NET Core)」選択時に自動で生成されるサンプルコード一式をそのまま流用しています。
エラーを表示する
コード例
ビューモデル
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace ErrorWebApplication.Models
{
public class ErrorViewModel
{
[DisplayName("入力項目")]
[Required(ErrorMessage = "入力項目は必須です。")]
public int InputValue { get; set; }
}
}
コントローラー
using ErrorWebApplication.Models;
using Microsoft.AspNetCore.Mvc;
namespace ErrorWebApplication.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
// POST: Home/Index
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(ErrorViewModel viewModel)
{
if (ModelState.IsValid)
{
if (viewModel.InputValue < 100)
{
// エラーの場合
ModelState.AddModelError(string.Empty, "入力値は100以上の値を指定してください。");
ModelState.AddModelError(string.Empty, "ちなみに入力値の範囲チェックはRangeAttributeが使えますよ。");
}
else
{
// 正常の場合
return RedirectToAction("Index");
}
}
return View(viewModel);
}
}
}
HTML
@model ErrorWebApplication.Models.ErrorViewModel
@{
ViewData["Title"] = "Error Page";
}
<h2>@ViewData["Title"].</h2>
<form asp-action="Index">
<div class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="InputValue" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="InputValue" class="form-control" />
<span asp-validation-for="InputValue" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary">実行</button>
</div>
</div>
</div>
</form>
実行結果
100より小さい値で入力した場合(サーバー側でエラーチェック)
楽ちん!
エラーをポップアップ表示する
上記コードを改造してポップアップ表示させてみます。
コード例
HTML
@model ErrorWebApplication.Models.ErrorViewModel
@{
ViewData["Title"] = "Error Page";
}
<h2>@ViewData["Title"].</h2>
<form asp-action="Index">
<div class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="InputValue" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="InputValue" class="form-control" />
<span asp-validation-for="InputValue" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary">実行</button>
</div>
</div>
</div>
</form>
<!-- ここまでは同じ -->
<!-- エラーメッセージ -->
<div class="modal fade" id="errorModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">エラー</h4>
</div>
<div class="modal-body text-danger">
メッセージ
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
$(function () {
// クライアント側のエラー結果を受け取り、ポップアップ表示する処理
$('form').each(function () {
var validator = $(this).data('validator');
validator.settings.showErrors = function (errorMap, errorList) {
if (this.errorList.length) {
this.defaultShowErrors();
var errorMessage = "";
$.each(errorList, function (index, value) {
errorMessage += value.message + '<br />';
});
showErrors(errorMessage);
}
}
});
// サーバー側のエラー結果を受け取り、ポップアップ表示する処理
$('.validation-summary-errors').each(function () {
var errors = $(this).find("li");
if (errors.length) {
var errorMessage = "";
$.each(errors, function (index, value) {
errorMessage += value.textContent + '<br />';
});
showErrors(errorMessage);
}
});
// ポップアップ表示する処理
function showErrors(errorMessage) {
var modal = $('#errorModal');
if (modal.data('bs.modal') == null || modal.data('bs.modal').isShown == false) {
modal.modal('show');
modal.find('.modal-body').html(errorMessage);
}
}
});
</script>
}
実行結果
[おまけ]もうちょっとエラー画面っぽくする
モーダルクラスのスタイルをいじるだけですが...
コード例
HTML
:
(省略)
:
<!-- エラーメッセージ -->
<div class="modal fade" id="errorModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content panel-danger">
<div class="modal-header panel-heading" style="border-top-left-radius: inherit; border-top-right-radius: inherit;">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title"><i class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></i> エラー</h4>
</div>
<div class="modal-body text-danger">
メッセージ
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
:
(省略)
:
※divタグのmodal-contentクラスとpanel-headingクラスの2行を弄っているだけです。
実行結果
こんな感じ