преобразование типа данных datetime2 в исключение типа данных datetime с датами после 1753/1/1 - PullRequest
0 голосов
/ 06 ноября 2018

Я добавил свойство к моей модели клиента , создал миграцию и обновил базу данных. Поле, созданное в БД: datetime . вот мой код модели

public DateTime BirthDate { get; set; }

вот представление, которое на самом деле является формой, в которую я вставляю дату и другие поля и отправляю форму.

<div class="form-group">
    @Html.LabelFor(m => m.Customer.BirthDate)
    @Html.TextBoxFor(m => m.Customer.BirthDate, "{0: dd-MM-yyyy}", new { @class = "form-control" })
</div>

и вот действие в контроллере

     public ActionResult Save(Customer customer)
    {
        if (customer.Id == 0)
        {
            _context.Customers.Add(customer);
        }
        else
        {
            var customerInDb = _context.Customers.Single(c => c.Id == customer.Id);
            customerInDb = customer;
        }
        _context.SaveChanges();
        return RedirectToAction("Index", "Customers");
    }

Я заполнил поле BirthDate значением 23/04/1976, отладил приложение и проверил значение customer.BirthDate, которое равно 23/04/1976 12:00:00 AM. Дата записана до 1753/1/1, но я получаю указанное исключение.

Я также попробовал следующее: Сделайте поле обнуляемым

public DateTime? BirthDate { get; set; }

исключение пропало, но дата не сохраняется в базе данных.

Удален формат "{0: dd-MM-гггг}" из представления, но тщетно.

вставленные даты в разных форматах, например 23 апреля 1952 года, 1985-12-01 и 1987/1/2, но не работали.

Visual Studio 2013 и база данных - LocalDb для Visual Studio.

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Фактическая проблема заключается как в DateTime свойстве viewmodel, так и в этом TextBoxFor помощнике:

@Html.TextBoxFor(m => m.Customer.BirthDate, "{0: dd-MM-yyy}", new { @class = "form-control" })

В зависимости от текущей настройки культуры, это сгенерирует простой ввод с указанным форматом даты, который может не совпадать с текущей настройкой культуры на сервере, что приводит к тому, что механизм связывания модели по умолчанию игнорирует его значение и использует DateTime.MinValue в качестве значения по умолчанию (потому что это не так обнуляемый тип), который не подходит для datetime типа столбца в SQL с минимальным значением 1753-01-01 (эквивалентный тип System.DateTime в T-SQL равен datetime2).

Наиболее рекомендуемая установка для создания помощника ввода для свойства DateTime использует DataTypeAttribute, установленный на DataType.Date и DisplayFormatAttribute, чтобы указать строку формата:

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime BirthDate { get; set; }

Затем используйте EditorFor или TextBoxFor с атрибутом type="date" для генерации ввода даты:

@* TextBoxFor *@
@Html.TextBoxFor(model => model.Customer.BirthDate, new { @class = "form-control", type = "date" }) 

@* EditorFor *@         
@Html.EditorFor(model => model.Customer.BirthDate, new { htmlAttributes = new { @class = "form-control" } })

Примечание: Те же настройки, что и выше, применяются и к свойству Nullable<DateTime> / DateTime?.

Кроме того, вы должны проверить для IsValid свойство ModelState перед использованием SaveChanges() и вернуть то же представление, когда проверка не удалась:

[HttpPost]
public ActionResult Save(Customer customer)
{
    if (ModelState.IsValid)
    {
        if (customer.Id == 0)
        {
            _context.Customers.Add(customer);
        }
        else
        {
            var customerInDb = _context.Customers.Single(c => c.Id == customer.Id);
            customerInDb = customer;
        }
        _context.SaveChanges();
        return RedirectToAction("Index", "Customers");
    }
    else
    {
        // validation failed, show the form again with validation errors
        return View(customer);
    }
}

Похожие проблемы: Дата ASP.NET MVC не сохраняется при публикации

0 голосов
/ 07 ноября 2018

Тот факт, что ошибка исчезает, если свойство обнуляется, дает ответ. Если значение было установлено , то вы получите точно такую ​​же ошибку, как если бы поле было not nullable.

Следовательно, значение не устанавливается, и в нем хранится значение NULL, если поле имеет значение NULL (подтверждается тем, что вы не сохраняете значение - оно хранит NULL).

Таким образом, для свойства, не имеющего значения nullable, если оно не установлено, оно будет иметь значение по умолчанию для точечной сети DateTime, равное DateTime.MinValue, которое будет действительным, если хранится на сервере SQL datetime2 но не в datetime, где вы получаете ошибку 1753.

Кстати, я предполагаю, что этот LocalDb в основном SQL-сервер, основанный на ошибке 1753. Для записи на сервере SQL вы должны использовать datetime2: DateTime2 против DateTime в SQL Server

Но это поле на самом деле Date, поэтому вы должны использовать date тип SQL.

Итак, в общем, я подозреваю, что значение BirthDate в Customer, переданное методу Save, имеет значение DateTime.MinValue. Теперь вам нужно понять, почему ... (но это другой вопрос)

P.S. Вы используете dd-MM-yyy специально? Должны ли быть дополнительные y?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...