4

私のビューモデル

Public Class ViewModel
  <SelectOne()>
  Public Property Collection As List(Of Item)
End Class

私のモデル

Public Class Item
  <SelectOneProperty(TargetValue:=True, ErrorMessage:="Select at least one.")>
  Public Property Selected As Boolean
  Public Property Value As String
End Class

私の見解ではViewModel.Collection、エディタ テンプレートでレンダリングしています

@Html.CheckBoxFor(Function(item) item.Selected)
@Html.HiddenFor(Function(item) item.Value)

ここで、クライアント側の検証を使用して、少なくとも 1 つのチェックボックスがオンになっていることを確認します。

プロパティにカスタム検証属性を設定しItem.Selected、新しいアダプターを登録することでこれを実現できます$.validator.unobtrusive.adapters.add()

しかし、コレクションのアイテムの1つがこのカスタム検証を使用してViewModel.Collectionいる場合、サーバー側ではすでに検証しているため、属性はむしろプロパティにあるべきだと思います:Selected = True

<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
Public Class SelectOneAttribute
    Inherits ValidationAttribute

    Protected Overrides Function IsValid(value As Object, validationContext As ValidationContext) As ValidationResult

        Dim list As IList

        If value Is Nothing Then
            Return Nothing
        End If

        If TypeOf value Is IEnumerable Then
            list = CType(value, IList)
        Else
            list = New Object() {value}
        End If

        Dim count As Integer = (From item In list
                                From prop In item.GetType().GetProperties()
                                Let attributes = prop.GetCustomAttributes(GetType(RequireOneOrMoreIndicatorAttribute), False)
                                Where attributes.Count > 0
                                From attribute In attributes
                                Where attribute.TargetValue = prop.GetValue(item, Nothing)).Count()
        If count > 0 Then
            Return Nothing
        End If

        Return New ValidationResult(FormatErrorMessage(validationContext.DisplayName))
    End Function
End Class

リフレクションを使用してSelectOnePropertyAttribute、チェックするプロパティを見つけます。

<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
Public Class SelectOnePropertyAttribute
    Inherits ValidationAttribute
    Implements IClientValidatable

    Public Property TargetValue As Object

    Public Sub New(targetValue As Object)
        Me.TargetValue = targetValue
    End Sub

    Public Overrides Function IsValid(value As Object) As Boolean
        Return True
    End Function

    Public Function GetClientValidationRules(metadata As System.Web.Mvc.ModelMetadata, context As System.Web.Mvc.ControllerContext) _
        As System.Collections.Generic.IEnumerable(Of System.Web.Mvc.ModelClientValidationRule) _
        Implements System.Web.Mvc.IClientValidatable.GetClientValidationRules

        Dim rule As New ModelClientValidationRule With {
            .ValidationType = "selectone",
            .ErrorMessage = Me.ErrorMessage
        }

        Return New ModelClientValidationRule() {rule}
    End Function
End Class

これがクライアント側の検証です

$.validator.unobtrusive.adapters.add("selectone", function (options) {
    options.rules["selectone"] = {};
    options.messages["selectone"] = options.message;
});

$.validator.addMethod("selectone", function (value, element, parameters) {

    var $el = $(element),
        name = $el.attr("name"),
        field = name.replace(/\[.*$/, "").replace(".", "_"),
        attr = name.replace(/^.*\./, ""),
        test = new RegExp(field + "\\[\\d\\]\." + attr);

    var inputs = $("input[id^=" + field + "]:not([disabled]):not([type=hidden])").filter("input[name$=" + attr + "]");

    for(var i = 0; i < this.errorList.length; i++) {
        var name = $(this.errorList[i].element).attr("name");

        // Do not write out the error more than once.
        if (test.test(name)) return true;
    }

    return inputs.length == 0 || inputs.filter(":checked:not([disabled])").val();
});
4

3 に答える 3

0

次の変更を行います: -

1.あなたのViewModel: -

Public Class ViewModel
  <SelectOne()>
  <SelectOneProperty(TargetValue:=True, ErrorMessage:="Select at least one.")>
  Public Property Collection As List(Of Item)
End Class
  1. 私のモデル: -

    Public Class Item Public Property Selected Boolean Public Property Value As String End Class

  2. ビューに次の行を追加します。

    @Html.HiddenFor(x=>x.ItemCollection)

4.次に、ビューを実行してビューのソースを表示すると、

4.次に、コードを送信すると、クライアント側の検証が実行されます。デバッガーを追加してデバッグする

5.次に、クライアント側のスクリプトを変更します。1.これで、すべてのチェックボックスから値を取得し、チェックボックスのいずれかが選択されていることを確認してからフォームを送信できます。それ以外の場合は結果を表示します。

6.また、必要に応じて SelectOnePropertyAttribute を変更します

7.サーバー側では、C#でこのコードを実行しました: -

[AttributeUsage((AttributeTargets.Field | AttributeTargets.Property), AllowMultiple = false, Inherited = false)] パブリック クラス SelectOneAttribute : ValidationAttribute { public String PropertyName { get; 設定; }

    protected override ValidationResult IsValid(object  value, ValidationContext validationContext)
    {
        bool boolVal = false;
        IList list;
        if (value == null)
        {
            return null;
        }
        if (value.GetType().Name == typeof(List<>).Name || value.GetType().Name == typeof(IList<>).Name)
        {
            list = (IList)value;
        }
        else
        {
            list = new object[] {value};
        }
        if (list.Count<0)
            return null;

        if ((from object item in list let propertyInfo = item.GetType().GetProperties() from info in propertyInfo where String.Equals(info.Name, PropertyName) && (bool)info.GetValue(item) == true select item).Any())
        {
            return null;
        }

        return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
    }
}
于 2012-09-18T14:31:45.600 に答える
0

これはあなたが必要とするものですか?「myCheckbox」がチェックされていない場合、フォームの送信が妨げられます...

$(document).ready(function () {
    $('#submitButtonId').click(function (e) {
        if ($('input[name=myCheckbox]:checked').length == 0) {
            e.preventDefault();
            alert('Please choose at least one checkbox before continuing!');
        }
    });
});
于 2012-09-21T15:24:07.833 に答える
0

サイド側で実行されるカスタム検証を作成していますが、クライアント側で実行する場合は、そのカスタム検証用の JQuery を作成してからページに追加する必要があります。

以下のリンクを参照してください。

http://www.codeproject.com/Articles/275056/Custom-Client-Side-Validation-in-ASP-NET-MVC3

http://www.falconwebtech.com/post/2012/04/21/MVC3-Custom-Client-Side-Validation-with-Unobtrusive-Ajax.aspx

于 2012-09-17T12:10:27.533 に答える