-1

MVC 5アプリケーションの特定のフィールドに対してカスタムの検証ルールを作成しました。編集フォームでうまく動作しますが、「作成」フォームの同じフィールドを検証すると、クライアント側の検証は実行されません - クライアント側の検証がトリガーされますが、私は何もメッセージは表示されません。それがないことがわかります。MVC控えめなカスタムルールは、クライアント上の1つのフォームでしか動作しません。

どちらの形式は同じモデルを使用しています。両方のビューは、すべてのスクリプトを持っているので、 スクリプトは_layoutページに追加されます。 どちらのビューはまったく同じかみそりのコードを持っていますValidationMessageFor()を含む

フォームがコントローラに到達すると、モデルはカスタムエラーのために有効ではないため、検証はクライアント側ではなくサーバ側で行われます。それは1つの形式では動作しますが、他の形式では動作しません。ここで

は私のコードです:

カスタム属性:

public class AtLeastOneRequiredAttribute : ValidationAttribute, IClientValidatable 
{ 
    public string OtherPropertyNames; 

    public AtLeastOneRequiredAttribute(string otherPropertyNames) 
    { 
     OtherPropertyNames = otherPropertyNames; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     string[] propertyNames = OtherPropertyNames.Split(','); 
     bool IsAllNull = true; 
     foreach(var i in propertyNames) 
     { 
      var p = validationContext.ObjectType.GetProperty(i); 
      var val = p.GetValue(validationContext.ObjectInstance, null); 
      if(val != null && val.ToString().Trim() != "") 
      { 
       IsAllNull = false; 
       break; 
      } 
     } 

     if(IsAllNull) 
     { 
      return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
     } 
     else 
     { 
      return null; 
     } 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var rules = new ModelClientValidationRule() 
     { 
      ErrorMessage = FormatErrorMessage(metadata.DisplayName), 
      ValidationType = "atleastonerequired" 
     }; 
     rules.ValidationParameters["otherpropertynames"] = OtherPropertyNames; 
     yield return rules; 
    } 
} 

クライアントコード:

$(function() { 
    $.validator.unobtrusive.adapters.addSingleVal("atleastonerequired", "otherpropertynames"); 
    $.validator.addMethod("atleastonerequired", function (value, element, params) { 
     var param = params.toString().split(','); 
     var IsAllNull = true; 
     $.each(param, function (i, val) { 
      var valueOfItem = $('#Activity_' + val).val().trim(); 
      if (valueOfItem != '') { 
       IsAllNull = false; 
       return false; 
      } 
     }); 
     if (IsAllNull) { 
      return false; 
     } 
     else { 
      return true; 
     } 
    }) 
}) 

ビュー - &作成フォームの編集は同じです:

@using (Html.BeginForm("Edit", "Activity", FormMethod.Post, new { @id = "editActivityForm" })) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form activity-form"> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     @Html.HiddenFor(model => model.Activity.RecordId) 


     <div class="form-group"> 
      @Html.LabelFor(model => model.Activity.Acres, htmlAttributes: new { @class = "control-label" }) 
      @Html.EditorFor(model => model.Activity.Acres, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Activity.Acres, "", new { @class = "text-danger" }) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Activity.Volume, htmlAttributes: new { @class = "control-label" }) 
      @Html.EditorFor(model => model.Activity.Volume, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Activity.Volume, "", new { @class = "text-danger" }) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Activity.Feet, htmlAttributes: new { @class = "control-label" }) 
      @Html.EditorFor(model => model.Activity.Feet, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Activity.Feet, "", new { @class = "text-danger" }) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Activity.Hours, htmlAttributes: new { @class = "control-label" }) 
      @Html.EditorFor(model => model.Activity.Hours, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Activity.Hours, "", new { @class = "text-danger" }) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Activity.Comment, htmlAttributes: new { @class = "control-label" }) 
      @Html.EditorFor(model => model.Activity.Comment, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Activity.Comment, "", new { @class = "text-danger" }) 
     </div> 

     <div class="form-group"> 
       <input type="submit" value="Save" class="btn btn-primary" onclick="$.validator.unobtrusive.parse($('#editActivityForm'));" /> 
     </div> 
    </div> 
} 

attirbuteを追加したモデル:

[AtLeastOneRequired("Acres,Volume,Feet,Hours", ErrorMessage = "Activity requires at least one measure - Acres, Volume, Feet or Hours.")] 
    public Nullable<int> Acres { get; set; } 
    public Nullable<int> Volume { get; set; } 
    public Nullable<int> Feet { get; set; } 
    public Nullable<int> Hours { get; set; } 
+0

説明を追加してもらえれば幸いです。私は何を追加するか分からない。私はすべてのコードを貼り付けることができますが、コードは両方のフォームで同じですので、どのように役立つか分かりません。私を助けるために、私は何を形作る必要がありますか? – BattlFrog

答えて

0

問題はクライアントコードにありました。私は最終的にクライアントコードがヒットしていないことを発見しました。私は最終的に、バリデーションの追加がinside(function(){})であったためだと判断しました。私はその「準備が整った」部分を削除しましたが、今は毎回動作します。

関連する問題