6

MVC 4データアノテーションを使用してカスタム検証を作成しようとしています。作成している検証は、制限的な検証ではなく、一種のメッセージプロンプトです。まず、ValidationAttributeクラスを継承し、IsValid()メソッドをオーバーライドしてデータをテストし、有効でない場合はValidationResultを返すカスタム検証クラスをいくつか作成しました。このデータを表示するビューには、EditorTemplatesを使用して、カスタムデータアノテーションと多くの組み込み検証を使用してかみそりで生成されたデータを表示する部分ビューがあります。これらはすべて、次のような形式でラップされます。

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))

私たちの要件は、ユーザーがデータをポストバックしてフォームを部分的に保存できるようにすることですが、無効なフィールドでプロンプトを表示するため、フォーム送信でCSSクラスを使用してポストバックを許可します

<input type="submit" value="Save" class="cancel"/>

これはすべて正常に機能していますが、ページの読み込み時にすべてのエラーメッセージを表示する必要がありますが、試してみるまで問題はありませんでした…</ p>

ここに示すように、フォームの有効なメソッドを呼び出す$(document).readyイベントでjqueryを使用した例をいくつか見つけました。

MVC3およびJQueryでの手動フォーム検証

しかし、これは私たちにとってはうまくいかなかったようです$('form')。Validate()は、フォーム検証を起動するように見える唯一の呼び出しは$('form')。valid()ではないようですが、これだけです[必須]属性などの組み込みの検証が表示されているようです。カスタム検証メッセージを表示する唯一の方法は、送信ボタンを使用してフォームをポストバックすることです。

初めてページを投稿せずにメッセージを表示するためにカスタムデータ注釈を取得する方法が必要ですか?どんな助けでも大歓迎です。

4

3 に答える 3

6

さて、私はそれが私が望んでいた/想像したよりも少し多くの仕事でしたが、私が望む結果を得る方法を見つけました。私が見逃していたのは、カスタム検証クラスでIClientValidatableを実装せず、カスタム検証を試したjQuery Validator addmethodに追加する必要があったが、カスタム検証クラスでIClientValidatableを実装しなかったため、すぐに実行します。すべてのjQueryのものがセットアップ/含まれていると仮定してこれを機能させる方法

まず、カスタム検証属性を使用する単純なモデルを作成します

public class Person
{
    [Required]
    [Display( Name="Name")]
    public string Name { get; set; }
    public int Age { get; set; }

    //Uses a custom data annotation that requires that at lease it self or the property name passed in the constructor are not empty
    [OneOfTwoRequired("Mobile")]
    public string Phone { get; set; }
    [OneOfTwoRequired("Phone")]
    public string Mobile { get; set; }
}

リフレクションを使用して、テストに渡される文字列名のプロパティを取得するカスタム検証クラス

2012年8月15日現在:MVC 4を使用している場合、ModelClientValidationRuleはMVC 4に存在しないようであるため、IClientValidatableを使用するにはSystem.web.mvc3.0を参照する必要があります。

public class OneOfTwoRequired : ValidationAttribute, IClientValidatable
    {
        private const string defaultErrorMessage = "{0} or {1} is required.";

        private string otherProperty;

        public OneOfTwoRequired(string otherProperty)
            : base(defaultErrorMessage)
        {
            if (string.IsNullOrEmpty(otherProperty))
            {
                throw new ArgumentNullException("otherProperty");
            }

            this.otherProperty = otherProperty;
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format(ErrorMessageString, name, otherProperty);
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            PropertyInfo otherPropertyInfo = validationContext.ObjectInstance.GetType().GetProperty(otherProperty);

            if (otherPropertyInfo == null)
            {
                return new ValidationResult(string.Format("Property '{0}' is undefined.", otherProperty));
            }

            var otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);

            if (otherPropertyValue == null && value == null)
            {
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }

            return ValidationResult.Success;
        }
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            yield return new ModelClientValidationRule
            {
                ErrorMessage = FormatErrorMessage(metadata.DisplayName),
                //This is the name of the method aaded to the jQuery validator method (must be lower case)
                ValidationType = "oneoftworequired"
            };

        }
    }

これをビューまたは部分ビューに追加します。これが$(document).readyメソッドに含まれていないことを確認する必要があります

    jQuery.validator.addMethod("oneoftworequired", function (value, element, param) {
        if ($('#Phone).val() == '' && $('#Mobile).val() == '')
            return false;
        else
            return true;
    });

    jQuery.validator.unobtrusive.adapters.addBool("oneoftworequired");

jQueryバリデーターは、ポストバックせずに、または最初のページの読み込み時にフォームを検証する場合にのみ必要と思われます。そのためには、$('form')。valid()を呼び出すだけです。

これが誰かに役立つことを願っています:)

于 2012-08-15T14:21:47.400 に答える
0

この記事は私を助けてくれました、それは動かされたようです、しかしそれはNugetパッケージで利用可能です...

http://www.eminencedigital.com/blog/index.php/2011/11/29/tracking-down-the-new-namespace-for-modelclientvalidationrule-in-asp-net-mvc-4-0-developer-プレビュー/

于 2013-01-03T13:21:44.690 に答える
0

スクリプトコードが「#Phone」と「#Mobile」のIDを持つフィールドに特に関連付けられているのに、C#コードが一般的で、任意の2つのフィールドに適用できるのはなぜですか。スクリプトを一般化する方法もありませんか?

于 2013-08-01T20:16:51.043 に答える