15

私のフォームには、(ラベルを使用するのではなく)入力内容についてユーザーをガイドするデフォルトのヘルパーテキストを含む入力があります。入力値がnullになることはないため、これにより検証が難しくなります。

これを処理するために、目立たない検証を拡張するにはどうすればよいですか?Name入力が「名前を入力してください...」と等しい場合、フォームは有効ではありません。

検証アダプターに関するBradWilsonのブログ投稿を読み始めましたが、これが正しい方法かどうかわかりません。フィールドに応じて異なるデフォルト値に対して検証できる必要があります。

ありがとう

4

6 に答える 6

34

カスタム検証属性を実装する方法を示すサンプルを次に示します。

public class NotEqualAttribute : ValidationAttribute, IClientValidatable
{
    public string OtherProperty { get; private set; }
    public NotEqualAttribute(string otherProperty)
    {
        OtherProperty = otherProperty;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var property = validationContext.ObjectType.GetProperty(OtherProperty);
        if (property == null)
        {
            return new ValidationResult(
                string.Format(
                    CultureInfo.CurrentCulture, 
                    "{0} is unknown property", 
                    OtherProperty
                )
            );
        }
        var otherValue = property.GetValue(validationContext.ObjectInstance, null);
        if (object.Equals(value, otherValue))
        {
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }
        return null;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = ErrorMessage,
            ValidationType = "notequalto",
        };
        rule.ValidationParameters["other"] = OtherProperty;
        yield return rule;
    }
}

そしてモデルで:

public class MyViewModel
{
    public string Prop1 { get; set; }

    [NotEqual("Prop1", ErrorMessage = "should be different than Prop1")]
    public string Prop2 { get; set; }
}

コントローラ:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            Prop1 = "foo",
            Prop2 = "foo"
        });
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

および表示:

@model MyViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    jQuery.validator.unobtrusive.adapters.add(
        'notequalto', ['other'], function (options) {
            options.rules['notEqualTo'] = '#' + options.params.other;
            if (options.message) {
                options.messages['notEqualTo'] = options.message;
            }
    });

    jQuery.validator.addMethod('notEqualTo', function(value, element, param) {
        return this.optional(element) || value != $(param).val();
    }, '');
</script>

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.Prop1)
        @Html.EditorFor(x => x.Prop1)
        @Html.ValidationMessageFor(x => x.Prop1)
    </div>
    <div>
        @Html.LabelFor(x => x.Prop2)
        @Html.EditorFor(x => x.Prop2)
        @Html.ValidationMessageFor(x => x.Prop2)
    </div>
    <input type="submit" value="OK" />
}
于 2011-04-21T10:01:23.233 に答える
3

はい、それが正しい方法です。独自の属性と実装を実装する必要がありますIClientValidatable

false非表示のフォーム フィールドとして、必要なブール値を最初に設定することもできます。ユーザーがテキストボックスを変更したら、true に設定します。

于 2011-04-20T21:20:55.460 に答える
0

ViewModel に IValidatableObject を実装させ、(IValidatableObject から) Validate メソッドを実装するときに、プロパティの値をチェックするロジックを追加することができます。

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
        var results = new List<ValidationResult>();

        if (Name == "Please enter your name...") 
            results.Add(new ValidationResult("You must enter a name");

        ...
        Enter other validation here
        ...     

        return results;
    }

これで、コントローラで Model.IsValid が呼び出されると、このロジックが実行され、通常どおり検証エラーが返されます。

于 2011-04-21T09:31:08.033 に答える
0

@Darin Dimitrovの回答を少し改善するには、を使用してリソースからメッセージを追加する場合は、ErrorMessageResourceName and ErrorMessageResourceTypeこれをエラーメッセージに追加するだけですErrorMessage = ErrorMessage ?? ErrorMessageString

ErrorMessageString は、これらのパラメーター (ErrorMessageResourceName および ErrorMessageResourceType) を使用してモデルに設定した、ローカライズされたバージョンのエラー メッセージを探します。

于 2016-01-18T18:39:20.813 に答える
-1

理想的なソリューションは、最小長と最大長を指定するカスタム属性と、MustNotContain="名前を入力してください..."です。

于 2011-04-20T22:03:48.507 に答える