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