全体的なデザイン
まず、ユーザーが警告を無視することを選択した場合、何らかの方法で追跡する必要があると思います。これを行う簡単で透過的な方法は、ユーザーが送信前にチェックする必要がある[警告を無視]チェックボックスを設定することです。もう 1 つのオプションは、フォームを 2 回送信し、2 回目の送信では警告を無視することです。その場合、おそらくIgnoreWarnings隠しフィールドが必要になるでしょう。他のデザインもあるかもしれませんが、簡単にするために最初のオプションを使用します。
要するに、アプローチは作成することです
- 警告タイプの検証をサポートするすべてのビュー モデルのカスタム データ注釈属性。
- ビュー モデルが継承する既知の基本クラス。
- カスタム属性ごとに、JavaScript でロジックを複製する必要があります。
以下のコードはアプローチを示しているだけであり、完全なコンテキストを知らなくてもかなり多くのことを想定する必要があることに注意してください。
モデルを見る
このシナリオでは、ビュー モデルを実際のモデルから分離することをお勧めします。これはとにかく良い考えです。考えられるアプローチの 1 つは、警告をサポートするすべてのビュー モデルの基本クラスを用意することです。
public abstract class BaseViewModel
{
public bool IgnoreWarnings { get; set; }
}
モデルを分離する必要がある主な理由は、IgnoreWarnings
プロパティをデータベースに保存する意味がほとんどないからです。
派生ビュー モデルは次のようになります。
public class YourViewModel : BaseViewModel
{
[Required]
[StringLengthWarning(MaximumLength = 5, ErrorMessage = "Your Warning Message")]
public string YourProperty { get; set; }
}
StringLengthWarning
サーバー側およびクライアント側の検証用のカスタム データ注釈属性です。最大長をサポートするだけで、他の必要なプロパティで簡単に拡張できます。
データ注釈属性
属性のコアはIsValid(value, validationContext
メソッドです。
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class StringLengthWarningAttribute : ValidationAttribute, IClientValidatable
{
public int MaximumLength { get; set; }
public override bool IsValid(object value)
{
return true;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = validationContext.ObjectInstance as BaseViewModel;
var str = value as string;
if (!model.IgnoreWarnings && (string.IsNullOrWhiteSpace(str) || str.Length > MaximumLength))
return new ValidationResult(ErrorMessage);
return base.IsValid(value, validationContext);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new StringLengthWarningValidationRule(MaximumLength, ErrorMessage);
}
}
この属性IClientValidatable
は、カスタム クライアント検証規則を実装して利用します。
public class StringLengthWarningValidationRule : ModelClientValidationRule
{
public StringLengthWarningValidationRule(int maximumLength, string errorMessage)
{
ErrorMessage = errorMessage;
ValidationType = "stringlengthwarning";
ValidationParameters.Add("maximumlength", maximumLength);
ValidationParameters.Add("ignorewarningsfield", "IgnoreWarnings");
}
}
クライアント側 JavaScript
最後に、これを機能させるには、ビューから次の JavaScript を参照する必要があります。
$(function () {
$.validator.addMethod('stringlengthwarning', function (value, element, params) {
var maximumlength = params['maximumlength'];
var ignorewarningsfield = params['ignorewarningsfield'];
var ctl = $("#" + ignorewarningsfield);
if (ctl == null || ctl.is(':checked'))
return true;
return value.length <= maximumlength;
});
$.validator.unobtrusive.adapters.add("stringlengthwarning", ["maximumlength", "ignorewarningsfield"], function (options) {
var value = {
maximumlength: options.params.maximumlength,
ignorewarningsfield: options.params.ignorewarningsfield
};
options.rules["stringlengthwarning"] = value;
if (options.message) {
options.messages["stringlengthwarning"] = options.message;
}
});
}(jQuery));
JavaScript は、再訪したくなるかもしれないいくつかの仮定を行います (チェックボックス名など)。
更新: HTML ヘルパー
エラーと警告の検証メッセージを別々に表示するには、いくつかのヘルパーが必要になります。次のクラスはサンプルを提供します。
public static class MessageHelpers
{
public static MvcHtmlString WarningMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] != null)
return htmlHelper.ValidationMessageFor(expression);
return MvcHtmlString.Empty;
}
public static MvcHtmlString ErrorMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] == null)
return htmlHelper.ValidationMessageFor(expression);
return MvcHtmlString.Empty;
}
}
ビューでは、通常どおり使用できます。
@Html.EditorFor(model => model.YourProperty)
@Html.ErrorMessageFor(model => model.YourProperty)
@Html.WarningMessageFor(model => model.YourProperty)