web-dev-qa-db-ja.com

@Htmlヘルパーによって生成されたMVCで「data-val-number」メッセージ検証を変更する方法

このモデルを仮定します:

Public Class Detail
    ...
    <DisplayName("Custom DisplayName")>
    <Required(ErrorMessage:="Custom ErrorMessage")>
    Public Property PercentChange As Integer
    ...
end class

そしてビュー:

@Html.TextBoxFor(Function(m) m.PercentChange)

このhtmlを続行します:

   <input data-val="true" 
    data-val-number="The field 'Custom DisplayName' must be a number." 
    data-val-required="Custom ErrorMessage"     
    id="PercentChange" 
    name="PercentChange" type="text" value="0" />

PercentChangeIntegerであるため、data-val-numberエラーメッセージをカスタマイズしたいと思います。 rangeを変更するような属性を探していました。
控えめなjsファイル自体を編集したり、クライアント側で上書きしたりする可能性があることを知っています。サーバー側の他のユーザーと同じようにdata-val-numberのエラーメッセージを変更したい。

74
GtEx

これは簡単ではありません。デフォルトのメッセージは、埋め込みリソースとしてSystem.Web.Mvcアセンブリに保存され、フェッチするメソッドは、内部のシールされた内部クラスのプライベート静的メソッド(System.Web.Mvc.ClientDataTypeModelValidatorProvider+NumericModelValidator.MakeErrorString)です。これは、Microsoftのコーディング担当者がトップシークレットを隠しているかのようです:-)

次の ブログ投稿 をご覧ください。解決策について説明しています。基本的に、既存の ClientDataTypeModelValidatorProvider をカスタムのものに置き換える必要があります。

必要なハードコアコーディングが気に入らない場合は、ビューモデル内のこの整数値を文字列に置き換え、解析を実行してカスタムエラーメッセージを提供するカスタム検証属性を設定することもできます(これはローカライズすることもできます)。

38
Darin Dimitrov

フィールドをレンダリングするときにdata-val-number属性を自分で指定することにより、メッセージをオーバーライドできます。これはデフォルトのメッセージを上書きします。これは、少なくともMVC 4で機能します。

@ Html.EditorFor(model => model.MyNumberField、new {data_val_number = "Supply an integer、dude!"})

Razorが属性を受け入れるには、属性名にアンダースコアを使用する必要があることに注意してください。

73
HenningJ

あなたがしなければならないことは:

Global.asaxApplication_Start()内に次のコードを追加します。

 ClientDataTypeModelValidatorProvider.ResourceClassKey = "Messages";
 DefaultModelBinder.ResourceClassKey = "Messages";

VSでASP.NET MVCプロジェクトを右クリックします。 Add => Add ASP.NET Folder => App_GlobalResourcesを選択します。

そのフォルダーに.resxというMessages.resxファイルを追加します。

これらの文字列リソースを.resxファイルに追加します。

FieldMustBeDate        The field {0} must be a date.
FieldMustBeNumeric     The field {0} must be a number.
PropertyValueInvalid   The value '{0}' is not valid for {1}.
PropertyValueRequired  A value is required.

必要に応じてFieldMustBeNumeric値を変更してください... :)

できました。


詳細については、この投稿を確認してください。

ASP.NET MVCおよびWebFormsのデフォルトエラーメッセージのローカライズ

50

これを回避する別の方法として、RegularExpression属性を適用して無効なエントリをキャッチし、そこにメッセージを設定しました。

[RegularExpression(@"[0-9]*$", ErrorMessage = "Please enter a valid number ")]

これはややハックですが、少なくとも私の特定の状況では、これは他のソリューションが提示する複雑さよりも望ましいと思われました。

編集:これはMVC3でうまく機能しましたが、MVC4 +のためのより良いソリューションがあるかもしれないようです。

23
Matthew Nichols

私が持っているMVC 3に関するこの本から。あなたがしなければならないのはこれです:

public class ClientNumberValidatorProvider : ClientDataTypeModelValidatorProvider 
{ 
   public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, 
                                                          ControllerContext context) 
   { 
       bool isNumericField = base.GetValidators(metadata, context).Any(); 
       if (isNumericField) 
           yield return new ClientSideNumberValidator(metadata, context); 
   } 
} 

public class ClientSideNumberValidator : ModelValidator 
{ 
  public ClientSideNumberValidator(ModelMetadata metadata,  
      ControllerContext controllerContext) : base(metadata, controllerContext) { } 

  public override IEnumerable<ModelValidationResult> Validate(object container) 
  { 
     yield break; // Do nothing for server-side validation 
  } 

  public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
  { 
     yield return new ModelClientValidationRule { 
        ValidationType = "number", 
        ErrorMessage = string.Format(CultureInfo.CurrentCulture,  
                                     ValidationMessages.MustBeNumber,  
                                     Metadata.GetDisplayName()) 
        }; 
  } 
} 

protected void Application_Start() 
{ 
    // Leave the rest of this method unchanged 

    var existingProvider = ModelValidatorProviders.Providers 
        .Single(x => x is ClientDataTypeModelValidatorProvider); 
    ModelValidatorProviders.Providers.Remove(existingProvider); 
    ModelValidatorProviders.Providers.Add(new ClientNumberValidatorProvider()); 
} 

ErrorMessageの生成方法に注意してください。現在のカルチャを指定すると、ValidationMessages(ここではカルチャ固有).resxリソースファイルからローカライズされたメッセージが抽出されます。不要な場合は、自分のメッセージに置き換えてください。

11
Denis Valeev

MVC3ソースを変更せずにメッセージクライアント側を変更する別のソリューションを次に示します。このブログ投稿の詳細:

https://greenicicle.wordpress.com/2011/02/28/fixing-non-localizable-validation-messages-with-javascript/

要するに、jQuery検証が読み込まれた後、次のスクリプトと 適切なローカライズファイル を含める必要があります。

(function ($) {
    // Walk through the adapters that connect unobstrusive validation to jQuery.validate.
    // Look for all adapters that perform number validation
    $.each($.validator.unobtrusive.adapters, function () {
        if (this.name === "number") {
            // Get the method called by the adapter, and replace it with one 
            // that changes the message to the jQuery.validate default message
            // that can be globalized. If that string contains a {0} placeholder, 
            // it is replaced by the field name.
            var baseAdapt = this.adapt;
            this.adapt = function (options) {
                var fieldName = new RegExp("The field (.+) must be a number").exec(options.message)[1];
                options.message = $.validator.format($.validator.messages.number, fieldName);
                baseAdapt(options);
            };
        }
    });
} (jQuery));
7
Phil Hale

ClientDataTypeModelValidatorProviderクラスのResourceKeyをFieldMustBeNumericキーを含むグローバルリソースの名前に設定して、numberのmvc検証エラーメッセージをカスタムメッセージに置き換えることができます。また、日付検証エラーメッセージのキーはFieldMustBeDateです。

ClientDataTypeModelValidatorProvider.ResourceKey="MyResources"; // MyResource is my global resource
4
reza taroosheh

純粋なjsの別のソリューションは、各アイテムのカスタムメッセージではなく、グローバルにメッセージを指定する場合に機能します。

重要なことは、検証メッセージは各要素のjquery.validation.unobtrusive.js属性を使用してdata-val-xxxを使用して設定されるため、ライブラリが使用する前にそれらのメッセージを置き換えるだけです。少し汚いですが、ただ仕事を早く終わらせたかったので、ここでは数値型の検証に進みます。

    $('[data-val-number]').each(function () {
    var el = $(this);
    var orig = el.data('val-number');

    var fieldName = orig.replace('The field ', '');
    fieldName = fieldName.replace(' must be a number.', '');

    el.attr('data-val-number', fieldName + ' باید عددی باشد')
});

良い点は、コンパイルを必要とせず、後で簡単に拡張できることですが、堅牢ではありませんが、高速です。

3
mohas

これもチェックしてください:

ASP.NET MVC 3の検証の完全ガイド-パート2

記事の主要部分は次のとおりです(コピーアンドペースト)。

クライアントとサーバーの両方で動作する完全に機能するカスタムバリデーターを作成するには、4つの異なる部分があります。最初にValidationAttributeをサブクラス化し、サーバー側の検証ロジックを追加します。次に、属性にIClientValidatableを実装して、HTML5 data-*属性をクライアントに渡すことを許可します。 3番目に、クライアントで検証を実行するカスタムJavaScript関数を作成します。最後に、HTML5属性をカスタム関数が理解できる形式に変換するアダプターを作成します。これは多くの作業のように聞こえますが、一度始めると、比較的簡単です。

ValidationAttributeのサブクラス化

この例では、あるプロパティの値が別のプロパティの値と等しくないことを単純にチェックするNotEqualToバリデータを記述します。

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class NotEqualToAttribute : ValidationAttribute
{
    private const string DefaultErrorMessage = "{0} cannot be the same as {1}.";

    public string OtherProperty { get; private set; }

    public NotEqualToAttribute(string otherProperty)
        : base(DefaultErrorMessage)
    {
        if (string.IsNullOrEmpty(otherProperty))
        {
            throw new ArgumentNullException("otherProperty");
        }

        OtherProperty = otherProperty;
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(ErrorMessageString, name, OtherProperty);
    }

    protected override ValidationResult IsValid(object value, 
        ValidationContext validationContext)
    {
        if (value != null)
        {
            var otherProperty = validationContext.ObjectInstance.GetType()
                .GetProperty(OtherProperty);

            var otherPropertyValue = otherProperty
                .GetValue(validationContext.ObjectInstance, null);

            if (value.Equals(otherPropertyValue))
            {
                return new ValidationResult(
                    FormatErrorMessage(validationContext.DisplayName));
            }
        }
    return ValidationResult.Success;
    }        
}

RegisterModelのパスワードプロパティに新しい属性を追加し、アプリケーションを実行します。

[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
[NotEqualTo("UserName")]
public string Password { get; set; }
...

IClientValidatableの実装

ASP.NET MVC 2には、クライアント側の検証を追加するメカニズムがありましたが、あまりきれいではありませんでした。ありがたいことに、MVC 3では状況が改善され、プロセスはかなり簡単になり、ありがたいことに旧バージョンのようにGlobal.asaxを変更する必要はありません

最初の手順は、カスタム検証属性でIClientValidatableを実装することです。これは、シンプルな1つのメソッドインターフェイスです。

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
    ModelMetadata metadata,
    ControllerContext context)
{
    var clientValidationRule = new ModelClientValidationRule()
    {
        ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
        ValidationType = "notequalto"
    };

    clientValidationRule.ValidationParameters.Add("otherproperty", OtherProperty);

    return new[] { clientValidationRule };
}

ここでアプリケーションを実行してソースを表示すると、パスワード入力htmlにnotequaltoデータ属性が含まれていることがわかります。

<div class="editor-field">
    <input data-val="true" data-val-notequalto="Password cannot be the same as UserName." 
    data-val-notequalto-otherproperty="UserName" 
    data-val-regex="Weak password detected." 
    data-val-regex-pattern="^(?!password$)(?!12345$).*" 
    data-val-required="The Password field is required." 
    id="Password" name="Password" type="password" />
    <span class="hint">Enter your password here</span>
    <span class="field-validation-valid" data-valmsg-for="Password" 
    data-valmsg-replace="true"></span>
</div>

カスタムjQuery検証関数の作成

このコードはすべて、個別のJavaScriptファイルに配置するのが最適です。

(function ($) {
    $.validator.addMethod("notequalto", function (value, element, params) {
        if (!this.optional(element)) {
            var otherProp = $('#' + params);
            return (otherProp.val() != 
        }
    return true;
});

$.validator.unobtrusive.adapters.addSingleVal("notequalto", "otherproperty");

}(jQuery));

検証要件によっては、jquery.validateライブラリに検証自体に必要なコードが既に含まれている場合があります。 jquery.validateには多くのバリデータが実装されていないか、データアノテーションにマップされていないため、これらがニーズを満たす場合、javascriptで記述する必要があるのはアダプターまたは組み込みアダプターへの呼び出しです。わずか1行にしてください。 jquery.validate.jsを見て、利用可能なものを確認してください。

既存のjquery.validate.unobtrusiveアダプターを使用する

アダプターの仕事は、フォーム要素のHTML5 data-*属性を読み取り、このデータをjquery.validateとカスタム検証関数が理解できるフォームに変換することです。ただし、すべての作業を自分で行う必要はありません。多くの場合、組み込みのアダプターを呼び出すことができます。 jquery.validate.unobtrusiveは、ほとんどの状況で使用できる3つの組み込みアダプターを宣言します。これらは:

jQuery.validator.unobtrusive.adapters.addBool - used when your validator does not need any additional data.
jQuery.validator.unobtrusive.adapters.addSingleVal - used when your validator takes in one piece of additional data.
jQuery.validator.unobtrusive.adapters.addMinMax - used when your validator deals with minimum and maximum values such as range or string length.

バリデーターがこれらのカテゴリーのいずれにも当てはまらない場合、jQuery.validator.unobtrusive.adapters.addメソッドを使用して独自のアダプターを作成する必要があります。これは見た目ほど難しくありません。記事の後半で例を参照します。

addSingleValメソッドを使用して、アダプターの名前と、渡したい単一の値の名前を渡します。検証関数の名前がアダプターと異なる場合、3番目のパラメーター(ruleName)を渡すことができます。

jQuery.validator.unobtrusive.adapters.addSingleVal("notequalto", "otherproperty", "mynotequaltofunction");

この時点で、カスタムバリデーターは完成しました。

理解を深めるために、 記事自体 を参照してください。これにより、詳細な説明とより複雑な例が示されます。

HTH。

2
Kamran

私はこれをして、正規表現を使用しました:

$(document).ready(function () {
    $.validator.methods.number = function (e) {
        return true;
    };
});


[RegularExpression(@"^[0-9\.]*$", ErrorMessage = "Invalid Amount")]
public decimal? Amount { get; set; }
1
Rob

または、単にこれを行うことができます。

@Html.ValidationMessageFor(m => m.PercentChange, "Custom Message: Input value must be a number"), new { @style = "display:none" })

お役に立てれば。

1
Edward Disi

KendoGridにこの問題があります。ビューの最後でスクリプトを使用してdata-val-numberをオーバーライドします。

@(Html.Kendo().Grid<Test.ViewModel>(Model)
  .Name("listado")
  ...
  .Columns(columns =>
    {
        columns.Bound("idElementColumn").Filterable(false);
    ...
    }

そして、少なくとも、Viewの最後に次のように記述します。

<script type="text/javascript">
        $("#listado").on("click", function (e) {
            $(".k-grid #idElementColumn").attr('data-val-number', 'Ingrese un número.');
        });    
</script>
0

私はこれを自分の考えに合わせて作ります

@Html.DropDownListFor(m => m.BenefNamePos, Model.Options, new { onchange = "changePosition(this);", @class="form-control", data_val_number = "This is my custom message" })
0
Fernando Campos