1

doubleモデルのタイプのプロパティに対応するテキストボックスの入力を検証しようとしています。ユーザーが入力した場合"foo"、エラーを表示できるように、それについて知りたいと思います。ただし、ValueProviderは値をサイレントにドロップしています(エラーはに追加されませんModelState)。

通常の送信では、フォーム"2"に対応するテキストボックスに入力しmyDoubleて送信します。検査controllerContext.HttpContext.Request.FormするとmyDouble=2、他の正しい入力の中でも、がわかります。bindingContext.ValueProvider.GetValue("myDouble") == 2、 予想通り。bindingContext.ModelState.Count == 6bindingContext.ModelState["myDouble"].Errors.Count == 0。_ すべてが良好で、モデルは期待どおりにバインドされます。

次に、フォームに対応するテキストボックスに「foo」と入力しmyDoubleて送信します。調べcontrollerContext.HttpContext.Request.FormmyDouble=fooみると、それは私が期待していたことです。ただし、bindingContext.ValueProvider.GetValue("myDouble") == nullbindingContext.ModelState.Count == 5正確な数は重要ではありませんが、以前より1つ少なくなっています)。を見ると、送信されなかっValueProviderたかのようmyDoubleになり、モデルのバインドは送信されなかったかのように発生します。これにより、不良入力と入力なしを区別することが困難になります。

これはの予想される動作ValueProviderですか?ValueProviderカスタムを実装せずに変換が失敗したときにレポートを取得する方法はありValueProviderますか?ありがとう!

4

2 に答える 2

1

ここでの問題の一部は、モデルのタイプがdouble.

問題は、doublenull にすることはできないため、デフォルトで 0 の値になるため、送信時に..ValueProviderが null を返した場合でも、フィールドの値は 0 のままで、検証はパスします。

Required 属性をdouble使用して、nullableを作成し、プロパティに追加する必要があります。double?タイプが不要な場合は、正規表現バリデーターを追加できます。

于 2012-10-22T22:48:08.237 に答える
0

IModelBinderを実装することにより、を使用してカスタムモデルバインディングロジックを実装できます。これにより、データ検証ロジックがモデルバインディングレベルになり、あらゆるタイプのValueProviderで使用できるようになります。あなたの状況では、モデルバインダーは、myDouble = "foo"がdoubleでない場合に判断し、無効な値を示すModelStateエラーに例外を追加します。

public class CustomDoubleBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }
        if (bindingContext == null)
        {
            throw new ArgumentNullException("bindingContext");
        }
        decimal tempDouble = 0m;
        if (bindingContext.ValueProvider.GetValue(bindingContext.ModelName) != null)
        {
            if (double.TryParse(bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue, out tempDecimal))
            {
                bindingContext.ModelState[bindingContext.ModelName].Errors.Add("Error parsing double value: " + bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue);
            }
        }

        return tempDouble;
    }
}

このカスタムモデルバインダーを作成したら、Global.asaxに登録する必要があります。

protected void Application_Start()
{
   ModelBinders.Binders[typeof(double)] = new CustomDoubleBinder();
}
于 2012-10-22T22:58:45.413 に答える