8

MVC のクライアント側で DateTime を検証するには、どのようなアプローチをお勧めしますか?

DateOfBirthという名前のプロパティを持つモデルがあるとしましょうDateTime

public class UserModel
{
    [DataType(DataType.Date)]
    public DateTime DateOfBirth {get;set;}
}

ビューには、単純なものがあります

<%: Html.LabelFor(model=>model.DateOfBirth) %>
<%: Html.EditorFor(model=>model.DateOfBirth) %>
<%: Html.ValidationMessageFor(model=>model.DateOfBirth) %>
<input type="submit" value="Submit" />

Microsoft MVC 検証または jQuery 検証のいずれかを使用できます。クライアント側で検証するために DateTime を取得するにはどうすればよいですか?

DataTypeAttribute が行うことはすべて、書式設定のヒントを提供することであり、実際には検証を行わないことを認識しています (その部分は ModelBinder に任せます)。

基本的に、投稿された値をモデルの DateOfBirth プロパティに入れようとしたときに ModelBinder が行うことを複製したいと考えています。

あなたの推奨事項は何ですか?

4

4 に答える 4

4

上で提案したように、カスタム検証に関する Phil Haack の投稿に従ってください: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

これが私がそれを行う方法です:


  1. 次のように、「DateFormatAttribute」クラスを追加します。

    public class DateFormatAttribute : ValidationAttribute {
      public override bool IsValid(object value) {    
        if (value == null) {
          return true;
        }

        // Note: the actual server side validation still has to be implemented :-)
        // Just returning true now...

        return true;
      }
    }

  1. 次のように、「DateFormatValidator」クラスを追加します。

    public class DateFormatValidator : DataAnnotationsModelValidator 
    {
      string message;

      public PriceValidator(ModelMetadata metadata, ControllerContext context
        , DateFormatAttribute attribute)
        : base(metadata, context, attribute) 
      {
        message = attribute.ErrorMessage;
      }

      public override IEnumerable GetClientValidationRules() 
      {
        var rule = new ModelClientValidationRule {
          ErrorMessage = message,
          ValidationType = "date" // note that this string will link to the JavaScript function we'll write later on
        };

        return new[] { rule };
      }
    }

  1. 上記のクラスを Global.asax.cs のどこかに登録します。

    DataAnnotationsModelValidatorProvider
        .RegisterAdapter(typeof(DateFormatAttribute), typeof(DateFormatValidator));

  1. クライアントに検証関数を追加します。これは、ユーザーのロケールに応じて実装する必要があることに注意してください。以下は、オランダ語 (nl-NL、nl-BE) のクライアント側検証関数です。

    /*
     * Localized default methods for the jQuery validation plugin.
     * Locale: NL
     */
    jQuery.extend(jQuery.validator.methods, {
        date: function(value, element) {
            return this.optional(element) || /^\d\d?[\.\/-]\d\d?[\.\/-]\d\d\d?\d?$/.test(value);
        }
    });

それは物事をカバーするはずです...

于 2010-09-03T13:07:51.727 に答える
1

ジョシュ、

あなたの問題はMVCで非常に一般的な問題です。つまり、modelbinderがフォームからモデルに入力された値をバインドしようとしているということです。明らかに、それが「適合しない」場合は、すぐにエラーが発生します。

では、modelbinderにカスタム検証を使用させるにはどうすればよいですか?エラーメッセージを返しますか?

さて、最初にフィル・ハークによって書かれたことを読んで実行してください。次に、カスタム検証があります。

次はです。モデルで整数と日時を使用しないでください。ユーザーがテキストボックスに好きなものを入力できる場合、これは常に問題を引き起こします。

あなたがすべきことは、あなたのオブジェクトのflatObjectを作ることです。

flatObjectは非常に単純です。これはオブジェクトであり、内部の変数の正確なコピーであり、instとdatetimeは文字列です(これらは常にmodelbinderでバインドされます)

例:

namespace MVC2_NASTEST.Models {

    public partial class FlatNieuw {
        public int Niw_ID { get; set; }
        public string Niw_Datum { get; set; }
        public string Niw_Titel { get; set; }
        public string Niw_Bericht { get; set; }
        public int Niw_Schooljaar { get; set; }
        public bool Niw_Publiceren { get; set; }
    }
}

私が持っている唯一のintはドロップダウンからのものであり、ドロップダウンの値がintである場合、それらは失敗しません。日付(データム)は文字列です。この文字列に対してカスタム検証を行います。modelbinderはこのFlatNieuwオブジェクトにバインドします。

私のNieuwクラスには、このクラスとまったく同じフィールド名があります。したがって、UpdateModel()を使用している場合でも、これは機能します。新しいエントリを作成する場合は、automapperを使用してこのflatObjectを通常のオブジェクトにマップできます。

これは、フィル・ハークのブログと一緒に、これを行う方法を教えてくれるはずだと思います。ご不明な点がございましたら、お気軽にお問い合わせください。

于 2010-09-06T08:13:19.810 に答える
0

私は同じ問題に直面しており、解決策を見つけることができません。誰もがこの問題に遭遇していないとは信じられません。私はjquery.maskedinput.jsモジュールを使用していて、それはうまく機能しましたが、日時入力にclass = "text-boxのクラスを割り当てる場合、「EditorFor」で「[DataType(DataType.Date)]」装飾を追加し始めたとき単線"。このクラスを追加すると、maskedinputjsが壊れます。また、下位の日付を「2/3/1010」としてフォーマットし、jqueryマスクの「99/99/9999」を吹き飛ばします。

于 2010-08-17T19:38:25.317 に答える
0

私の経験によると、Microsoft MVC の検証または jQuery の検証のいずれかが、開発中の一部のプロジェクトにとって過剰な場合があります。そのため、自分で小さなものをコーディング/グラブすることがあります。

解決策 1: カスタム プラグイン (自分に合った方法に変更できます)

(function($) {
    $.fn.extend({
            ValidateInput: function() {
                var bValid = true;
                this.removeClass('ui-state-error');
                this.each(function() {
                    if ($(this).hasClass('date')) {

                            var valdate = checkRegexp($(this), /^(([0-2]\d|[3][0-1])\/([0]\d|[1][0-2])\/[1-2]\d{3})$/, "date format is wrong, please input as dd/MM/yyyy, e.g. 02/28/2010");
                            if (!valdate) {
                                $(this).val("input in 'dd/mm/yyyy' format");
                            }
                            bValid = bValid && valdate;
                return bValid;

                        }
                }); 

    }});

    function checkRegexp(o, regexp, n) {
        if (!(regexp.test(o.val()))) {
            o.addClass('ui-state-error');
            //updateTips(n);
            return false;
        } else {
            return true;
        }
        }

 })(jQuery);

あなたの見解で:

  1. class='date' を入力ボックスに追加します
  2. プラグインを呼び出す $("#yourInput").alidateInput();

解決策 2: Jquery UI Date Pick を使用する (現在使用している解決策)

     <script language="javascript" type="text/javascript">
            $(function() {
// use date picker to your textbox input 
                $(".yourInput").datepicker();
                $(".yourInput").datepicker('option', { dateFormat: "dd/mm/yy" });
// disable any human input to the textbox input
                $(".yourInput").keyup(function() {
                    $(this).val("");
                });
            });
        </script>

ソリューション 2 の詳細: http://www.gregshackles.com/2010/03/templated-helpers-and-custom-model-binders-in-asp-net-mvc-2/

于 2010-09-09T05:16:26.377 に答える