0

データ注釈を介してカスタムデータ検証を追加しようとしています。現時点では、サーバー側の検証についてのみ懸念しています。私がここや他の場所で見たものはすべて、クライアント側の検証を参照しています。すべてのコードを削除し、いくつかのテストケースを実行しました。これは通常のビューで問題なく機能しますが、フォームが部分ビューになるとすぐに、IsValidをオーバーライドするメソッドでコードが壊れなくなります。

どちらの場合も、カスタム属性が初期化されているのがわかります。フォームが通常のビューにある場合、フォームの送信時にオーバーライドメソッドが実行されているのがわかりますが、部分的なビューにある場合、コードは実行されず、HttpPostアクションに直接移動します。

私はこれを理解しようとして2日間の大部分を費やし、途方に暮れています。どんな助けでも大歓迎です。

注:以下のコードは、HttpPostアクションに入るときに同じビューを返します。私はテスト目的でこのようにしています。オーバーライドが部分ビューから呼び出されることはないため、IsValidは常にtrueです。

検証が機能するフォームを表示するビュー

@model eRecruitBoard.ViewModels.HomeIndexViewModel
@{
    ViewBag.Title = "eRecruitBoard";
}
@*<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>*@

<h2>Login/homepage</h2>

<br /><br />
 <div class="errorMessage">
 @Html.DisplayFor(m => m.LoginErrorMsg)
</div>
<br />

@using (Html.BeginForm("Index", "Home")) {
    <div id="loginControlBox">
        <fieldset>
            <legend>Welcome to eRecruitBoard</legend> 

            <div class="editor-label">
                @Html.LabelFor(m => m.UserName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.UserName)
                @Html.ValidationMessageFor(m => m.UserName)
            </div>

            <div class="editor-label">
                @Html.LabelFor(m => m.Password)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(m => m.Password)
                @Html.ValidationMessageFor(m => m.Password)
            </div>

            <div class="editor-label">
                @Html.CheckBoxFor(m => m.RememberMe)
                @Html.LabelFor(m => m.RememberMe)
            </div>
            <div class="editor-label">
                @Html.EditorFor(m => m.Date)
                @Html.ValidationMessageFor(m => m.Date)
            </div>
            <p>
                <input type="submit" value="Log In" />
            </p>
        </fieldset>
    </div>
}
    <div>
        @Html.Action("BlankForm", "TestForm")
    </div>

部分ビュー(これらのスクリプト呼び出しも_Layoutを介して行われますが、テスト用にもここにあります)

@model eRecruitBoard.ViewModels.TestFormViewModel

    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>    
    <script src="@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/MicrosoftMvcValidation.js")" type="text/javascript"></script>

@using (Html.BeginForm("NewActivity2", "TestForm", FormMethod.Post))
{
<fieldset>
    <legend>Test Form</legend>
    <br />
    @Html.LabelFor(m => m.Date)
    @Html.EditorFor(m => m.Date)
    @Html.ValidationMessageFor(m => m.Date)
    <input id="activityTimelineSubmit" type="submit" value="Submit" />
</fieldset>
}

ViewModel(部分ビュー用)

namespace eRecruitBoard.ViewModels
{
    public class TestFormViewModel
    {
        [Required]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
        [NonFutureDate()]
        [Display(Name = "Date")]
        public DateTime Date { get; set; }
    }
}

コントローラ(部分表示用)

namespace eRecruitBoard.Controllers
{
    public class TestFormController :BaseController
    {
        public ActionResult BlankForm()
        {
            var viewModel = new TestFormViewModel
            {
                Date = DateTime.Today
            };

            return PartialView("_TestForm", viewModel);
        }

        [HttpPost]
        public ActionResult NewActivity2(DateTime Date)
        {
            if (!ModelState.IsValid)
                return RedirectToAction("Index", "Home");
            else
                return RedirectToAction("Index", "Home");
        }
    }
}

検証コード

using System;
using System.ComponentModel.DataAnnotations;

namespace eRecruitBoard.WebLibrary.Validation
{
    [AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
    public class NonFutureDateAttribute : ValidationAttribute  //public sealed class 
    {
        public NonFutureDateAttribute(): base("Activity can only be saved for today or dates in the past.")
        {
        }
        public override bool IsValid(object value)
        {
            DateTime dateToCheck = (DateTime)value;
            return (dateToCheck <= DateTime.Today);
        }
    }
}
4

1 に答える 1

2

RedirectToActionすべての検証を失った場合。return PartialView(model)POSTアクションで行う必要があります。そのためには、パラメータタイプNewActivity2をのTestFormViewModel代わりにに変更する必要がありますDateTime

@Html.Partial()それでも機能しない場合は、部分ビュー(またはjavascript)を表示する方法の例でコードを更新します。

于 2012-10-13T11:07:47.793 に答える