Связующее по умолчанию в ASP.NET MVC: слишком длинные целые, пустое сообщение об ошибке проверки - PullRequest
7 голосов
/ 06 июня 2011

У меня есть следующий класс модели (для простоты):

public class Info
{
    public int IntData { get; set; }
}

Вот моя форма Razor, которая использует эту модель:

@model Info
@Html.ValidationSummary()
@using (Html.BeginForm())
{
    @Html.TextBoxFor(x => x.IntData)
    <input type="submit" />
}

Теперь, если я введу нечисловые данные в текстовое поле, я получу правильное сообщение проверки, т. Е. «Значение« qqqqq »недопустимо для поля« IntData »».

Но если я введу очень длинную последовательность цифр (например, 345234775637544), я получу ПУСТОЙ отчет о проверке.

В коде моего контроллера я вижу, что ModelState.IsValid равен false, как ожидалось, а ModelState["IntData"].Errors[0] выглядит следующим образом:

{System.Web.Mvc.ModelError}
ErrorMessage: ""
Exception: {"The parameter conversion from type 'System.String' to type 'System.Int32' failed. See the inner exception for more information."}

(exception itself) [System.InvalidOperationException]: {"The parameter conversion from type 'System.String' to type 'System.Int32' failed. See the inner exception for more information."}
InnerException: {"345234775637544 is not a valid value for Int32."}

Как видите, проверка работает нормально, но не выдает сообщение об ошибке пользователю.

Можно ли настроить поведение подшивки модели по умолчанию, чтобы в этом случае отображалось правильное сообщение об ошибке? Или мне придется написать пользовательский переплет?

Ответы [ 2 ]

8 голосов
/ 09 июня 2011

Один из способов - написать пользовательское связующее для модели:

public class IntModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (value != null)
        {
            int temp;
            if (!int.TryParse(value.AttemptedValue, out temp))
            {
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, string.Format("The value '{0}' is not valid for {1}.", value.AttemptedValue, bindingContext.ModelName));
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
            }
            return temp;
        }
        return base.BindModel(controllerContext, bindingContext);
    }
}

, которое можно зарегистрировать в Application_Start:

ModelBinders.Binders.Add(typeof(int), new IntModelBinder());
1 голос
/ 10 июня 2011

Как насчет установки MaxLength в поле ввода на 10 или около того?Я бы сделал это в сочетании с установкой диапазона на IntData.Если, конечно, вы не хотите, чтобы пользователь вводил 345234775637544. В этом случае вам лучше использовать строку.

...