Неправильный целочисленный ввод не вызывает ошибку при заполнении модели - PullRequest
0 голосов
/ 11 сентября 2018

В модели MVC, в которой список объектов представлен в виде свойства, MVC 5 (и, по крайней мере, еще в 3) не выдает ошибку, если значение, представленное для целочисленного свойства, не может быть проанализировано как целое число.

MCVE

Следующий пример кода демонстрирует проблему:

C #:

using System.Web.Mvc;

namespace ModelBindingTest
{
    public class MyModel
    {
        public int NotNullValue { get; set; }
        public int? NullableValue { get; set; }
    }

    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            ViewBag.Method = "GET";
            return View(new MyModel()
            {
                NotNullValue = 999,
                NullableValue = 777,
            });
        }

        [HttpPost]
        public ActionResult Index(MyModel model)
        {
            ViewBag.Method = "POST";
            return View(model);
        }
    }
}

Home.cshtml:

@model ModelBindingTest.MyModel
@{
    Layout = null;
}

<!DOCTYPE html>

<html lang="en">    
<body>
    <form action="" method="POST">
        <label for="NotNullValue">NotNullValue:</label>
        <input id="NotNullValue" name="NotNullValue" value="@Model.NotNullValue">
        <label for="NullableValue">NullableValue:</label>
        <input id="NullableValue" name="NullableValue" value="@Model.NullableValue">
        <button type="submit">Save</button>
    </form>
    <p>HTTP Method: @ViewBag.Method </p>
</body>
</html>

HTML в основном удобен для наблюдения за тем, что происходит. Это также воспроизводится путем размещения JSON. Вот результаты, которые я получаю:

  • 222 для NotNullValue: model.NotNullValue равно 222, как и ожидалось.
  • Пробел NotNullValue: model.NotNullValue равен 0.
  • Буквы для NotNullValue (например, hre): model.NotNullValue равно 0.
  • 222 для NullableValue: model.NullableValue равно 222, как и ожидалось.
  • Пробел NullableValue: model.NullableValue is null.
  • Буквы для NullableValue (например, hre): model.NullableValue равно null.

Пожалуйста, игнорируйте тот факт, что я повторно использую объект модели для запросов GET и POST. Я не делаю это в производстве (хотя я видел это сделано); это просто упрощение для демонстрации.

Цель

Я хочу, чтобы MVC фактически выдавал ошибку, если он не может проанализировать входные данные для типа, указанного в объекте модели. Поведение как есть может преобразовывать недопустимые значения в допустимые, что приводит к сохранению данных, которые клиент, вероятно, не намеревался.

Поведение букв в свойстве int? особенно проблематично для меня, поскольку у меня есть поле, в котором мне нужно разрешить null в качестве допустимого значения.

Я бы предпочел ошибку 400, но на данный момент любая ошибка является улучшением.

Вещи, которые я пробовал

  • Изменение модели на требуемые значения. Я получаю «Не определен конструктор без параметров для этого объекта». ошибка, независимо от того, какие значения представлены.
  • Измените тип ввода на string и подтвердите его самостоятельно. Конечно. Я могу сделать это. Я также могу просто выбросить всю инфраструктуру MVC и использовать что-то еще. Практически нет смысла иметь строго типизированные объекты модели, если я пойду по этому пути.
  • Измените ввод на параметр метода. Это почти работает, в некоторой степени. Это вызывает ответ 500 с сообщением об ошибке «Словарь параметров содержит пустую запись для параметра« NotNullValue »...». Но, как следует из сообщения об ошибке, он не работает для int?. Это также нежизнеспособно при производстве, так как некоторые из моих данных состоят из списков объектов модели неизвестной длины, которые описывают поведение отдельных элементов независимо от того, является ли список свойством модели или параметром метода .

Что я могу сделать, чтобы заставить MVC фактически рассматривать ошибку синтаксического анализа как ошибку?

ASP.NET Core MVC

Я не знаю, отличается ли поведение в Core MVC. Если это так, то переключение на Core может быть полезным ответом для кого-то другого (и я бы не стал отказываться от него), но в настоящий момент это неосуществимо для меня. Так что я ищу другой обходной путь.

...