こんにちは、Noyです。
今回はASP.NET MVCのバリデーションについてです。
問題
「後から読み込んだ部分ビューのクライアント検証が効かない」
Modelには以下のデータアノテーションを付けています。入力が空、もしくは文字数が500文字を超えたらエラーメッセージを出してほしいのですが出てくれません。
public partial class Comment
{
~省略~
[DisplayName("コメント")]
[Required(ErrorMessage = "{0}が空です")]
[StringLength(500, ErrorMessage ="{0}は{1}文字以内にしてください")]
public string context { get; set; }
~省略~
}
編集ボタンがクリックされたら、非同期で以下の部分ビュー(編集フォーム)を読み込んで表示しています。
@model YumeSetori.Models.Comment
@using (Html.BeginForm("EditComment", "Home", FormMethod.Post))
{
<div class="d-flex ml-5">
<div class="input-group align-items-end">
@Html.TextAreaFor(Model => Model.context, new { @class = "underline form-control", rows = "1", placeholder = "コメントを入力", id = "editComment-textarea" })
@Html.Hidden("comment_id", Model.comment_id)
</div>
</div>
<div class="align-items-center d-flex mt-2">
@Html.ValidationMessageFor(Model => Model.context)
<div class="ml-auto">
<div class="btn btn-secondary" onclick="cancelEdit('@(Model.comment_id)')">キャンセル</div>
<input class="btn btn-primary" id="sendComment" type="submit" value="送信" disabled>
</div>
</div>
}
部分ビューを読み込むコードは以下。HomeコントローラーのEditCommentアクションにGETリクエストを投げます。
// コメント編集フィールドを準備
var editComment = function (id) {
var $thisComment = $("#" + id);
var actionUrl = '@Url.Action("EditComment", "Home")' + '?commentId=' + id;
$thisComment.find(".edit-comment").load(actionUrl);
}
一応、アクションは以下。
public ActionResult EditComment(Guid commentId)
{
if (commentId == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
HomeWorkerService workerService = new HomeWorkerService();
Comment comment = workerService.GetComment(commentId);
if (comment == null)
{
return HttpNotFound();
}
return PartialView("_EditComment", comment);
}
解決策
部分ビューを読み込んだ後に以下のjQueryコードを実行します。
$.validator.unobtrusive.parse($('form'));
こいつを実行することで、 HTML DOM を走査して、「data-val-○○」といった “控えめ JavaScript” 方式のためのマークアップを探しだし、適切にイベントハンドラを付けてあげることができるようです。
参考情報
以下記事のおかげで解決できました。ありがとうございますm(__)m
コメント