1

数値フィールドの MVC 検証のデフォルトの動作をオーバーライドする方法を見つけることができないようです。

私の問題を表すデフォルトの MVC4 プロジェクトを作成しました。

モデル (デフォルトの MVC 4 コンストラクトに加えて、「Age」と「Date」の 2 つのプロパティ):

    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    public DateTime Date { get; set; }

    public int Age { get; set; }

したがって、デフォルトでは、MVC は作成した 2 つのフィールドを検証し、次の検証メッセージが表示されます。「フィールド「年齢」は必須です」および「フィールド「日付」は必須です」

今私が達成しようとしているのは、アプリケーションにデフォルトの数値検証を無視させることです (クライアント側でこれを行っており、ユーザーが無効な値を入力することは不可能です)。Null 非許容プロパティにデフォルトの「必須」属性を追加しないように MVC を強制しようとしました。

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

これは私にいくつかの進歩をもたらしました。現在、「必須」の検証は行われませんが、フォームを投稿すると、「値が必要です」という 2 つの同一の検証メッセージが返されます。

この点を超えて何も達成できませんでした。ClientDataTypeModelValidatorProvider を削除しようとしました

        foreach (ModelValidatorProvider prov in ModelValidatorProviders.Providers)
        {
            if (prov.GetType().Equals(typeof(ClientDataTypeModelValidatorProvider)))
            {
                break;
            }
        }

すべてのプロバイダーと同様に

ModelValidatorProviders.Providers.Clear();

成功せずに。

また、MVC が DataAnnotationsModelValidatorProvider で使用している既定の属性の一部をオーバーロードしようとしましたが、結果は得られませんでした。

そこで、この状況についていくつか質問したいことがあります。

  1. Null 非許容データ型について、MVC がサーバー側でデフォルトの検証を行わないようにすることは可能ですか? 可能であればどのように?
  2. 質問 1 で説明されている検証のデフォルトの動作を変更することは可能ですか? 可能であれば - どのように?
  3. このカスタム バリデーター/検証属性の代わりに、MVC にカスタム バリデーター/検証属性を強制的に使用させることはできますか? 可能であれば - どのように?

また、注意:検証を行う属性を記述して、検証を行う必要があるすべてのプロパティに配置したくありませんデフォルトの検証を行う方法に関するルールを定義できるソリューションを探しています。

事前に感謝します。

4

1 に答える 1

1

用の独自の ModelBinder を作成しますint。次に、そのバインダーがエラー時に 0 を返すようにします。

public class IntModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        ValueProviderResult valueResult = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName);
        ModelState modelState = new ModelState { Value = valueResult };
        object actualValue = null;
        try
        {
            actualValue = Convert.ToInt32(valueResult.AttemptedValue,
                System.Globalization.CultureInfo.InvariantCulture);
        }
        catch (FormatException e)
        {
            //Uncomment for default error
            //modelState.Errors.Add(e);
            actualValue = 0;
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

そして Global.asax でApplication_Start()

ModelBinders.Binders.Add(typeof(int), new IntModelBinder());
于 2013-10-29T11:58:28.813 に答える