52

私はこのようなビューモデルを持っています:

public class SignUpViewModel
{
    [Required(ErrorMessage = "Bitte lesen und akzeptieren Sie die AGB.")]
    [DisplayName("Ich habe die AGB gelesen und akzeptiere diese.")]
    public bool AgreesWithTerms { get; set; }
}

ビューのマークアップ コード:

<%= Html.CheckBoxFor(m => m.AgreesWithTerms) %>
<%= Html.LabelFor(m => m.AgreesWithTerms)%>

結果:

検証は実行されません。bool は値型であり、null になることはないため、ここまでは問題ありません。しかし、AgreesWithTerms をヌル可能にしても、コンパイラーが叫ぶため、機能しません。

「テンプレートは、フィールド アクセス、プロパティ アクセス、単一次元配列インデックス、または単一パラメーターのカスタム インデクサー式でのみ使用できます。」

それで、これを処理する正しい方法は何ですか?

4

12 に答える 12

98

私の解決策は次のとおりです(すでに提出された回答と大差ありませんが、より良い名前が付けられていると思います):

/// <summary>
/// Validation attribute that demands that a boolean value must be true.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value;
    }
}

次に、モデルで次のように使用できます。

[MustBeTrue(ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }
于 2010-04-25T23:31:46.287 に答える
51

サーバー側とクライアント側の両方にバリデーターを作成します。MVC と目立たないフォーム検証を使用すると、次の手順を実行するだけでこれを実現できます。

まず、プロジェクトにクラスを作成して、次のようにサーバー側の検証を実行します。

public class EnforceTrueAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        if (value == null) return false;
        if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties.");
        return (bool)value == true;
    }

    public override string FormatErrorMessage(string name)
    {
        return "The " + name + " field must be checked in order to continue.";
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = String.IsNullOrEmpty(ErrorMessage) ? FormatErrorMessage(metadata.DisplayName) : ErrorMessage,
            ValidationType = "enforcetrue"
        };
    }
}

これに続いて、モデルの適切なプロパティに注釈を付けます。

[EnforceTrue(ErrorMessage=@"Error Message")]
public bool ThisMustBeTrue{ get; set; }

最後に、次のスクリプトをビューに追加して、クライアント側の検証を有効にします。

<script type="text/javascript">
    jQuery.validator.addMethod("enforcetrue", function (value, element, param) {
        return element.checked;
    });
    jQuery.validator.unobtrusive.adapters.addBool("enforcetrue");
</script>

注:GetClientValidationRules注釈をモデルからビューにプッシュするメソッドは既に作成しています。

于 2012-01-27T16:03:39.927 に答える
19

カスタム属性を作成して取得しました。

public class BooleanRequiredAttribute : RequiredAttribute 
{
    public override bool IsValid(object value)
    {
        return value != null && (bool) value;
    }
}
于 2010-02-11T15:17:14.743 に答える
7
[Compare("Remember", ErrorMessage = "You must accept the terms and conditions")]
public bool Remember { get; set; }
于 2014-03-05T14:08:40.463 に答える
7

これは「ハック」かもしれませんが、組み込みの Range 属性を使用できます。

[Display(Name = "Accepted Terms Of Service")]
[Range(typeof(bool), "true", "true")]
public bool Terms { get; set; }

唯一の問題は、「警告」文字列に「FIELDNAME は True と True の間にある必要があります」と表示されることです。

于 2013-06-03T21:55:44.073 に答える
4

ここでは、「必須」は間違った検証です。「必須」と同じではない「値が true でなければならない」に似たものが必要です。次のようなものを使用するのはどうですか:

[RegularExpression("^true")]

?

于 2010-02-11T15:06:25.250 に答える
3

私は既存のソリューションを最大限に活用し、サーバー側とクライアント側の両方の検証を可能にする単一の回答にまとめています。

bool 値が true であることを確認するためにプロパティをモデル化するために適用するには、次のようにします。

/// <summary>
/// Validation attribute that demands that a <see cref="bool"/> value must be true.
/// </summary>
/// <remarks>Thank you <c>http://stackoverflow.com/a/22511718</c></remarks>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute, IClientValidatable
{
    /// <summary>
    /// Initializes a new instance of the <see cref="MustBeTrueAttribute" /> class.
    /// </summary>
    public MustBeTrueAttribute()
        : base(() => "The field {0} must be checked.")
    {
    }

    /// <summary>
    /// Checks to see if the given object in <paramref name="value"/> is <c>true</c>.
    /// </summary>
    /// <param name="value">The value to check.</param>
    /// <returns><c>true</c> if the object is a <see cref="bool"/> and <c>true</c>; otherwise <c>false</c>.</returns>
    public override bool IsValid(object value)
    {
        return (value as bool?).GetValueOrDefault();
    }

    /// <summary>
    /// Returns client validation rules for <see cref="bool"/> values that must be true.
    /// </summary>
    /// <param name="metadata">The model metadata.</param>
    /// <param name="context">The controller context.</param>
    /// <returns>The client validation rules for this validator.</returns>
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        if (metadata == null)
            throw new ArgumentNullException("metadata");
        if (context == null)
            throw new ArgumentNullException("context");

        yield return new ModelClientValidationRule
            {
                ErrorMessage = FormatErrorMessage(metadata.DisplayName),
                ValidationType = "mustbetrue",
            };
    }
}

目立たない検証を利用するために含める JavaScript。

jQuery.validator.addMethod("mustbetrue", function (value, element) {
    return element.checked;
});
jQuery.validator.unobtrusive.adapters.addBool("mustbetrue");
于 2014-03-19T16:07:43.160 に答える
3

私の解決策は、ブール値のこの単純なカスタム属性です。

public class BooleanAttribute : ValidationAttribute
{
    public bool Value
    {
        get;
        set;
    }

    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value == Value;
    }
}

次に、モデルで次のように使用できます。

[Required]
[Boolean(Value = true, ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }
于 2010-04-06T17:54:41.983 に答える
2

クライアント側で検証のためにこれを機能させるのに問題がある人 (以前の私) の場合:

  1. 含まれる <% Html.EnableClientValidation(); %> ビュー内のフォームの前
  2. フィールドに <%= Html.ValidationMessage または Html.ValidationMessageFor を使用
  3. カスタム検証タイプのルールを返す DataAnnotationsModelValidator を作成しました
  4. DataAnnotationsModelValidator から派生したクラスを Global.Application_Start に登録しました

http://www.highoncoding.com/Articles/729_Creating_Custom_Client_Side_Validation_in_ASP_NET_MVC_2_0.aspx

これを行うための優れたチュートリアルですが、ステップ 4 を見逃しています。

于 2011-04-28T17:17:37.560 に答える
2

これを行う適切な方法は、型をチェックすることです!

[Range(typeof(bool), "true", "true", ErrorMessage = "You must or else!")]
public bool AgreesWithTerms { get; set; }
于 2016-01-18T20:28:03.483 に答える
1

[RegularExpression] を追加するだけで十分です。

[DisplayName("I accept terms and conditions")]
[RegularExpression("True", ErrorMessage = "You must accept the terms and conditions")]
public bool AgreesWithTerms { get; set; }

注 - 「True」は大文字の T で始まる必要があります

于 2015-05-07T11:57:37.733 に答える
1

ここでより完全なソリューションを見つけました(サーバー側とクライアント側の両方の検証):

http://blog.degree.no/2012/03/validation-of-required-checkbox-in-asp-net-mvc/#comments

于 2012-10-10T03:09:33.593 に答える