Как можно интегрировать модель-представление-контроллер (MVC) с реляционной базой данных?

Как можно обойти ошибку ModelState, требующую заполнения и `CountryId` и `Country` одновременно при добавлении связанных записей в базу данных из `asp-form`?
  • 8 мая 2024 г. 22:30
Ответы на вопрос 3
Для интеграции модели-представления-контроллера (MVC) с реляционной базой данных в ASP.NET можно использовать Entity Framework, который позволяет работать с базой данных через объектно-ориентированный подход. 

Для того чтобы обойти ошибку ModelState при добавлении связанных записей в базу данных из asp-form, можно использовать атрибут [Bind("CountryId, Name")] в методе POST контроллера. Этот атрибут позволяет указать только те поля, которые должны быть привязаны к модели, игнорируя остальные поля. Например:

```csharp
[HttpPost]
public IActionResult AddCountry([Bind("CountryId, Name")] Country country)
{
    if (ModelState.IsValid)
    {
        // Добавление страны в базу данных
        _context.Countries.Add(country);
        _context.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(country);
}
```

Таким образом, при добавлении связанных записей в базу данных из asp-form, можно указать только необходимые для сохранения поля и обойти ошибку ModelState, требующую заполнения всех полей модели.
Сложные объекты, как раз могут передаваться, просто надо сделать формы другим образом. Скорее всего ты в этот asp-form передаешь всю модель. Предполагаю, что вся модель - это Address. 
Да, из вложенных сложных структур плохо создаются формы. Для решения тебе надо будет форму вручную: все поля и их связь с моделью прописывать самому. Есть шаблонные помощники (Html.EditorFor и другие) - используй их.
Например, так (внимание, написал по воспоминаниям, может даже не компилироваться)
@Html.BeginForm() 
{
      <label>Страна</label>
      @Html.EditorForModel(x => x.Country)
      <label>Город</label>
      @Html.EditorForModel(x => x.City)
}


Кроме этого, есть пара других советов:
1. Создай специальные DTO классы, которые будут потом отображаться в эти объекты БД.
2. Раз ты делаешь через asp-form, то лушче добавь специальные атрибуты валидации: EmailAddress, Range и т.д.

P.S. в 1 пункте проблема глубже, чем простой маппинг. Если делать такой подход, который показан:
- Изменения схемы БД потребуют изменения UI
- Клиент может передать данные, о которых он знать не должен (например, добавишь новое поле куда-нибудь и оно случайно обновится)
Как подружить MVC с реляционной базой данных?

Та нормально они дружат через Entity Framework, Dapper либо другие ORM.

Форма не может передать методу POST сложные типы

А при чём тут ваш вопрос " Как подружить MVC с реляционной базой данных? ", если вы не можете передать с клиента на сервер?

ModelState требует, чтоб были заполнены и CountryId, и Country одновременно.

Используйте модели. Просто создайте другой класс (Модель), который будете использовать для get/post запросов (По отдельности, одна модель - один запрос) и вынесите туда всё, что вам нужно. Обычно вам хватит только Id того объект с каким будете работать + поля, которые нужны для создания/обновления/добавления и т.д. Для удаления вам хватит просто Id, для обновления нужны только поля, которые нужно обновить и Id того объекта, который нужно обновлять. И будет вам работа с примитивами )

Для валидации вообще рекомендую накатить какую-то библиотеку по типу Fluent Validation Api либо Regex (Приоритетно)
Похожие вопросы