Отправка POST-запроса с использованием ViewModel

Вопрос или проблема

Отправка POST-запроса с использованием ViewModel

Я создаю веб-сайт, на котором вы можете создать мероприятие для игры. У меня есть страница создания. На странице есть поле GameID при создании нового события. Я пытаюсь использовать модель представления (ViewModel), чтобы отображать название игры и выбирать его, вместо ID.

public class EventCreateVM
{
    public Events Event { get; set; }
    public IEnumerable<SelectListItem> Games { get; set; }
}
public class Events
{
    public int EventID { get; set; }
    public int GameID { get; set; }
    [DisplayName("Название мероприятия")]
    public string EventName { get; set; }
    public string Server { get; set; }
    [DisplayName("Максимальное количество игроков")]
    public int MaxPlayers { get; set; }
    public string Type { get; set; }
    public string Platform { get; set; }
    public string Description { get; set; }
    [DisplayName("Время мероприятия")]
    public DateTime DateTime { get; set; }
}

Я изменил страницу создания, чтобы она работала с моделью представления.

@model AgileTeamFour.UI.ViewModels.EventCreateVM

@{
    ViewData["Title"] = "Создать";
}
<h1>Создать</h1>

<h4>Мероприятия</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create" asp-controller="Event">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
           @*  <div class="form-group">
                <label asp-for="Event.EventID" class="control-label"></label>
                <input asp-for="Event.EventID" class="form-control" />
                <span asp-validation-for="Event.EventID" class="text-danger"></span>
            </div> *@
            <div class="form-group">
    <label asp-for="Event.GameID" class="control-label"></label>
    <select asp-for="Event.GameID" class="form-control" asp-items="Model.Games"></select>
    <span asp-validation-for="Event.GameID" class="text-danger"></span>
</div>
            <div class="form-group">
                <label asp-for="Event.EventName" class="control-label"></label>
                <input asp-for="Event.EventName" class="form-control" />
                <span asp-validation-for="Event.EventName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.Server" class="control-label"></label>
                <input asp-for="Event.Server" class="form-control" />
                <span asp-validation-for="Event.Server" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.MaxPlayers" class="control-label"></label>
                <input asp-for="Event.MaxPlayers" class="form-control" />
                <span asp-validation-for="Event.MaxPlayers" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.Type" class="control-label"></label>
                <input asp-for="Event.Type" class="form-control" />
                <span asp-validation-for="Event.Type" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.Platform" class="control-label"></label>
                <input asp-for="Event.Platform" class="form-control" />
                <span asp-validation-for="Event.Platform" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.Description" class="control-label"></label>
                <input asp-for="Event.Description" class="form-control" />
                <span asp-validation-for="Event.Description" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.DateTime" class="control-label"></label>
                <input asp-for="Event.DateTime" class="form-control" />
                <span asp-validation-for="Event.DateTime" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Создать" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Назад к списку</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

И изменил контроллер.


public ActionResult Create()
{
    var games = GameManager.Load(); 
    var viewModel = new EventCreateVM
    {
        Event = new Events(),
        Games = games.Select(g => new SelectListItem
        {
            Value = g.GameID.ToString(),
            Text = g.GameName
        }).ToList()
    };
    return View(viewModel);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(EventCreateVM viewmodel)
{
    try
    {
        if (ModelState.IsValid)
        {
            int eventID = 0;
            EventManager.Insert(ref eventID, viewmodel.Event.GameID, viewmodel.Event.EventName, viewmodel.Event.Server, viewmodel.Event.MaxPlayers, viewmodel.Event.Type, viewmodel.Event.Platform, viewmodel.Event.Description, viewmodel.Event.DateTime);
            return RedirectToAction(nameof(Index));
        }
        return View(viewmodel);
    }
    catch
    {
        return View();
    }
}

Страница корректно формирует список выбора игр. Но когда я нажимаю кнопку отправки, страница просто обновляется и ничего не создается в базе данных.

Форма, кажется, выглядит нормально, насколько я могу судить. Запрос возвращает 200, и, похоже, не возникает ошибок. Функция создания работает нормально, если я не использую изменения модели представления. Я пробовал несколько часов выяснить, в чем дело, но безуспешно. Буду благодарен за любой совет.

Судя по вашему коду, запрос отправляется на API “Event/Create” с GET вместо POST (метод HTTP), когда форма отправляется.

Вы можете отладить, установив точку останова в первой строке кода для обоих методов API “Event/Create” с GET и POST. Это поможет вам определить, попадает ли API “Event/Create” (с методом POST) в обработку.

В resumen, добавьте атрибут method="POST" к элементу <form>, чтобы убедиться, что форма отправляется на правильный API.

<form asp-action="Create" asp-controller="Event" method="POST">
    ...
</form>

Ответ или решение

При создании веб-сайта для планирования событий игр, вы столкнулись с проблемой, когда форма на странице создания события не обрабатывает POST-запрос правильно. Давайте разберем ваши шаги и предложим решение.

Проблема

Вы создали контроллер и представление, использующие ViewModel, и всё выглядело нормально: список игр формируется корректно, но после нажатия кнопки отправки происходит только обновление страницы и события не создаются в базе данных. Это может быть связано с тем, что форма не отправляется с методом POST.

Решение

  1. Проверьте метод формы: Убедитесь, что ваша форма действительно использует метод POST. Для этого добавьте атрибут method="POST" к вашему элементу <form>:

    <form asp-action="Create" asp-controller="Event" method="POST">
       ...
    </form>
  2. Отладка: Чтобы убедиться, что метод Create с POST запросом вызывается, вы можете установить точки останова в начале методов Create в контроллере. Это поможет вам определить, получает ли ваш контроллер запрос.

  3. Проверка состояния модели: Убедитесь, что модель проходит валидацию перед вставкой данных в базу. Для этого вам нужно убедиться, что все обязательные поля заполнены и соответствуют заданным требованиям. Если валидация не проходит, данные не будут добавлены в базу:

    if (ModelState.IsValid)
    {
       // Вставка данных
    }
    else
    {
       // Верните обратно ту же ViewModel с ошибками
       return View(viewmodel);
    }
  4. Логи ошибок: Если данные не добавляются, вам следует рассмотреть возможность ведения логов ошибок. Это поможет вам зафиксировать любые исключения или проблемы, возникающие при вставке данных в базу. Например:
    catch (Exception ex)
    {
       // Логируйте ошибку
       // return View(viewmodel);
    }

Полный Пример

Примените изменения, как показано ниже:

<form asp-action="Create" asp-controller="Event" method="POST">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Event.GameID" class="control-label"></label>
        <select asp-for="Event.GameID" class="form-control" asp-items="Model.Games"></select>
        <span asp-validation-for="Event.GameID" class="text-danger"></span>
    </div>
    <!-- Другие поля формы -->
    <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
    </div>
</form>

Заключение

После внесения всех вышеуказанных изменений повторите попытку отправить форму. Убедитесь, что все поля формы заполнены правильно, и проверьте, срабатывает ли метод POST в контроллере. Если проблема сохраняется, вам стоит проверить логи и отладить данные, отправляемые с формы. Удачи!

Оцените материал
Добавить комментарий

Капча загружается...