Как можно интегрировать модель-представление-контроллер (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. <br/> Да, из вложенных сложных структур плохо создаются формы. Для решения тебе надо будет форму вручную: все поля и их связь с моделью прописывать самому. Есть <a href="https://metanit.com/sharp/aspnet5/9.4.php" rel="nofollow">шаблонные помощники</a> (Html.EditorFor и другие) - используй их. <br/> Например, так (внимание, написал по воспоминаниям, может даже не компилироваться) <br/> <pre><code class="csharp">@Html.BeginForm() 
{
      &lt;label&gt;Страна&lt;/label&gt;
      @Html.EditorForModel(x =&gt; x.Country)
      &lt;label&gt;Город&lt;/label&gt;
      @Html.EditorForModel(x =&gt; x.City)
}</code></pre> <br/> <br/> Кроме этого, есть пара других советов: <br/> 1. Создай специальные DTO классы, которые будут потом отображаться в эти объекты БД. <br/> 2. Раз ты делаешь через asp-form, то лушче добавь специальные атрибуты валидации: EmailAddress, Range и т.д. <br/> <br/> P.S. в 1 пункте проблема глубже, чем простой маппинг. Если делать такой подход, который показан: <br/> - Изменения схемы БД потребуют изменения UI <br/> - Клиент может передать данные, о которых он знать не должен (например, добавишь новое поле куда-нибудь и оно случайно обновится)
<blockquote>Как подружить MVC с реляционной базой данных?</blockquote> <br/> Та нормально они дружат через Entity Framework, Dapper либо другие ORM. <br/> <br/> <blockquote>Форма не может передать методу POST сложные типы</blockquote> <br/> А при чём тут ваш вопрос " <i>Как подружить MVC с реляционной базой данных?</i> ", если вы не можете передать с клиента на сервер? <br/> <br/> <blockquote>ModelState требует, чтоб были заполнены и CountryId, и Country одновременно.</blockquote> <br/> Используйте модели. Просто создайте другой класс (Модель), который будете использовать для <code>get/post</code> запросов (По отдельности, одна модель - один запрос) и вынесите туда всё, что вам нужно. Обычно вам хватит только Id того объект с каким будете работать + поля, которые нужны для создания/обновления/добавления и т.д. Для удаления вам хватит просто Id, для обновления нужны только поля, которые нужно обновить и Id того объекта, который нужно обновлять. И будет вам работа с примитивами ) <br/> <br/> Для валидации вообще рекомендую накатить какую-то библиотеку по типу <code>Fluent Validation Api</code> либо <code>Regex</code> (Приоритетно)
Похожие вопросы