2011-01-14 13 views
5

2つのパスワード文字列を比較するビューをレイアウトしています。私のモデルの一つで二つの特性は非常に簡単です:CompareAttribute DataAnnotationのクライアント側の検証が実行されない

[Required] 
    [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")] 
    [StringLength(20, MinimumLength = 6)] 
    [DataType(DataType.Password)] 
    [Display(Name = "New Password")] 
    public string NewPassword { get; set; } 

    [Required] 
    [DataType(DataType.Password)] 
    [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")] 
    [StringLength(20, MinimumLength = 6)] 
    [Display(Name = "Confirm Password")] 
    [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 
    public string ConfirmPassword { get; set; } 

ここに私のビューのコードは次のとおりです。

<table class="fieldset center" width="400"> 
    <tbody> 
     <tr> 
      <th width="150"> 
       @Html.LabelFor(m => m.NewPassword) 
      </th> 
      <td> 
       @Html.PasswordFor(m => m.NewPassword, new { @class = "itext3" }) 
       <br /><br />@Html.ValidationMessageFor(m => m.NewPassword) 
      </td> 
     </tr>      
     <tr> 
      <th width="150"> 
       @Html.LabelFor(m => m.ConfirmPassword) 
      </th> 
      <td> 
       @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "itext3" }) 
       <br /><br />@Html.ValidationMessageFor(m => m.ConfirmPassword) 
      </td> 
     </tr> 
    </tbody> 
</table> 

CompareAttribute上を除いて、試験した場合、属性のすべてが彼らのクライアント側の検証メッセージを発射しますConfirmPasswordはサーバーに到達するまで起動しません。しかし、私のコントローラでは、ModelState.IsValid = falseです。

私が行っていることを正しく動作しているデフォルトのMVCアプリケーションと比較しました。トラブルシューティングとこれを修正するための提案はありますか?

私はMVC 3 RTMを使用しています。

答えて

4

_Layout.cshtmlのスクリプトタグを見てください。私はおそらくあなたのjQueryの参考資料であると推測しています。 MVC 3のプロジェクトフォームのスクラッチを開始しましたか、またはサンプルプロジェクトなどを使用していますか?

ここで私は何が起こったのですか。私は

  • 私は例えば、SRCにajax.microsoft.com指さ
  • だから、属性いくつかのサンプルコードを使用していた...同じような問題があったスクリプトタグの一つは、このように見えた:<script src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script>
  • クライアント側でjsが実行されているものをよりうまく処理したいので、これに変更しました:<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
  • これは単なる例ですが、変更したスクリプトタグがいくつかあったと思います。

内部で提供されたjQueryファイルに変更した後、それは機能しました。私は戻って、私のlocal.validate.jsファイルを見て...それはバージョン1.6でした。これは、問題がjQueryのバージョンやそれ以外のjsライブラリと互換性があったためです。

ボトムラインは、私が持っていたvalidate.unobtrusive.js libで1.7が完全に機能していないようです... 1.7で機能する新しいバージョンがあるかもしれません...私が言ったように、私はいくつかの未知のものがあるので、サンプルプロジェクトを手直ししていました。私は、MvcValidation.jsライブラリとの間に互換性があり、他のjsライブラリとの間で互換性がないと思いますか?

いずれにしても、問題を述べる最も簡単な方法は、おそらくjsライブラリの悪い組み合わせを参照している可能性が高いということです。私はjsのライブラリの良い組み合わせを得るための最高のフェールセーフの方法は、Visual Studioで新しいAsp.Net MVC 3プロジェクトを作成し、どのバージョンがデフォルトで/あなたがプロジェクトテンプレートであなたを与える参照してください...と仮定しているだろうあなたが最初からプロジェクトを開始していないということです。あなたが最初からそれを開始した場合は、あなたのレイアウトファイルを悪いjs参照を持つように変更しているかもしれません。そうでなければVisualStudioプロジェクトテンプレートに問題があると思いますか?しかし、疑わしいです。すべてのことが言った - 私はとにかく賭けたいと思う最も可能性の高い理由は、すぐにいくつかの例のコードを使用しようとしている私のような問題になったということです=)

+0

それはそれだった。あなたは実際に私が持っていた2つの問題を解決しました。 http://stackoverflow.com/questions/4752877/remote-validation-in-asp-net-mvc-3-how-to-use-additionalfields-in-action-methodあなたがそこに行って、この質問、私はあなたにも答えをあげます。ありがとうございました! – beaudetious

1

私はASP.NET MVC 3 RTMでこれをテストしてみた、それは私のためにうまく働いた:

モデル:

public class MyViewModel 
{ 
    [Required] 
    [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")] 
    [StringLength(20, MinimumLength = 6)] 
    [DataType(DataType.Password)] 
    [Display(Name = "New Password")] 
    public string NewPassword { get; set; } 

    [Required] 
    [DataType(DataType.Password)] 
    [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")] 
    [StringLength(20, MinimumLength = 6)] 
    [Display(Name = "Confirm Password")] 
    [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 
    public string ConfirmPassword { get; set; } 
} 

コントローラー:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel()); 
    } 

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

ビュー:

@model SomeAppName.Models.MyViewModel 
@{ 
    ViewBag.Title = "Home Page"; 
} 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 
@using (Html.BeginForm()) 
{ 
    @Html.LabelFor(m => m.NewPassword) 
    @Html.PasswordFor(m => m.NewPassword) 
    @Html.ValidationMessageFor(m => m.NewPassword) 
    <br/> 

    @Html.LabelFor(m => m.ConfirmPassword) 
    @Html.PasswordFor(m => m.ConfirmPassword) 
    @Html.ValidationMessageFor(m => m.ConfirmPassword) 

    <br/> 
    <input type="submit" value="OK" /> 
} 

この構成では、c lient side validationは[Compare]を含むすべての属性に対して完璧に機能します。

+0

これは私が実証したのと同じことです。私は別のことをしているのか分かりません。 – beaudetious

+0

@ beaudious、あなたのソースコードを見ることができない、あるいは記述しているエラーを再現できない人にとっては、あまり明らかではありません。気になるのは、FireBugでjavascriptエラーを探すことです。 –

+0

ありがとうダーリン。しましょう。もし私がそれが簡単な間違いであると分かったら(99%の可能性があります)、答えとして返信します。 – beaudetious

8

jquery .validate.unobtrusive.js(およびjquery.validate.unobtrusive.min.js、縮小版)。 [比較]属性の結果として出力されるクライアント側の検証は、比較フィールドがフォームの最初のフィールドである場合にのみ機能します。このバグを修正するには、jquery.validate.unobtrusive.jsにこの行を検索します。

この等価になり
element = $(options.form).find(":input[name=" + fullOtherName + "]")[0]; 

element = $(options.form).find(":input[name=MyExample.Control]")[0]; 

残念ながらそれは見つけるための正しい構文は()ではない、と原因フォーム上の最初の入力コントロールを参照します。この等価になり

element = $(options.form).find(":input[name='" + fullOtherName + "']")[0]; 

:に並ぶ

変更

element = $(options.form).find(":input[name='MyExample.Control]'")[0]; 

正しく正しい構文で、指定した名前の入力コントロールと一致します。

次のようになりますjquery.validate.unobtrusive.min.jsで同じコード・ブロック、探して:私は作ることができなかった

f=a(b.form).find(":input[name='"+d+"']")[0]; 
+0

パーフェクト。これは答えになったはずです!私はjquery.validate.unobtrusive.min.jsでMark Shapiroの修正を採用し、jQuery 1.8.2およびjQuery Validation Plugin 1.9.0とともに使用しています。チャームとして働く:) – Kayes

1

f=a(b.form).find(":input[name="+d+"]")[0]; 

をし、それを変更しますデフォルトの作業方法。 JQueryのように、JQuery.validatorに登録されている検証メソッドのみを起動します。当初、私はこのような何かをやっていた

...

jQuery.validator.unobtrusive.adapters.add("equaltopropertyvalidation", ["param"], function (rule) 
    { 
     alert("attaching custom validation adapter."); 
     rule.rules["equaltopropertyvalidation"] = rule.params.param; 
     rule.messages["equaltopropertyvalidation"] = rule.message; 

     return function (value, element, param) 
     { 
      alert("now validating!"); 
      return value == this.currentForm[param].value; 
     }; 
    }); 

しかし、(今の検証!)私の第二の警告にもかかわらず、最初のものは希望発火することはありません。私はthisの記事を見ていましたが、私は余分な何かをする必要があるので、私はこのように実装することをためらっていましたが、私は怠け者でした。

何が間違っているかを把握するために多くの時間を費やした後、私はこの記事の示唆した方法で実装しました。これは今のようなものです。

<script type="text/javascript"> 

    jQuery.validator.addMethod("equaltopropertyvalidation", function (value, element, param) 
    { 
     return value == this.currentForm[param].value; 
    }); 

    jQuery.validator.unobtrusive.adapters.add("equaltopropertyvalidation", ["param"], function (rule) 
    { 
     rule.rules["equaltopropertyvalidation"] = rule.params.param; 
     rule.messages["equaltopropertyvalidation"] = rule.message; 
    }); 

</script> 

詳細のようなあなたがここにある場合:このフィールドが有効であるかによってかどうかを確認するために解雇された機能ですjquery.validate.jsに見て、

 check: function (element) 

を検索フィールド上で適用可能なすべてのルールを実行します。今度は、最初に、それを起動する配列を作成します。これは、次のコードを使用して行います。

 var rules = $(element).rules(); 

そしてそれは、ルールのコレクションを反復処理コレクション内のすべての項目のためのルール要素を作成し、その規則に発射する対応する方法を見つけよう。メソッドが見つかると、メソッドは起動されます。これは、次のコードを使用して行います。

 var result = $.validator.methods[method].call(this, element.value.replace(/\r/g, ""), element, rule.parameters); 

今重要なことは、カスタムメソッドをJQuery.validator.addMethodを使用して$ .validator.methodsコレクションに追加されていない場合、それはjQueryの中でそこに座っていてもITは、検出されませんということです.validator.unobtrusive.adaptersコレクション。

は(はい、その後誰かが明確にしてください場合)JQuery.validator.addMethodを使用せずに、この作品を作るための方法があるかもしれませんが、私は信じて、これは第二のアプローチは動作し、第一にはない理由です。

私はjQueryのファイルの以下のバージョンを使用していた

  1. はJQuery:1.6/1.7.1
  2. Jquery.Validate:1.9.0
  3. JQuery.Unobtrusive.Validate: にMicrosoft CDNから撮影2/14/2012
関連する問題