HttpPost и привязка модели, что мне не хватает?

У меня есть 2 таблицы/класса: фильмы и актеры, а также промежуточная таблица, связанная с ними. Я пытаюсь создать новую запись в промежуточной таблице, чтобы создать новую связь и добавить новый фильм в фильмографию актера.

Вот класс ViewModel:

    public class ActorsUpdateFilmsViewModel
    {
        public Actor actor { get; set; }

        public IQueryable<Film> bindedFilms { get; set; }

        [DisplayName("Title")]
        public int FilmId { get; set; }

        public int ActorId;
    }

Представление, в котором вы можете выбрать несвязанный фильм из поля со списком:

<div class = "right">
    <div class = "right">
        <h3>Add a film:</h3>
        <form asp-action = "Bind">
            <div asp-validation-summary = "ModelOnly" class = "text-danger"></div>
            <div class = "form-group">
                <label asp-for = "FilmId" class = "control-label"></label>
                <select asp-for = "FilmId" class = "form-control" asp-items = "ViewBag.Unbinded"></select>
                <span asp-validation-for = "FilmId" class = "text-danger"></span>
            </div>
            <input type = "hidden" asp-for = "actor.ActorId" />
            <input type = "hidden" asp-for = "@Model.actor" />
            <input type = "hidden" asp-for = "@Model.bindedFilms" />
            <div class = "form-group">
                <input type = "submit" value = "Bind" class = "btn btn-success" />
            </div>
        </form>
    </div>
</div>

Затем контроллер, который извлекает данные:

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Bind(int id, [Bind("actor,FilmId,bindedFilms, ActorId")]ActorsUpdateFilmsViewModel model) 
        {
            if (ModelState.IsValid)
            {
                if (model.FilmId != null)
                {
                    FilmsAndActor newBinding = new FilmsAndActor()
                    {
                        FilmIdFk = model.FilmId,
                        ActorIdFk = model.actor.ActorId
                    };

Элемент newBinding отлично подходит для добавления его в промежуточную таблицу и связывания актера и фильма. Но ModelState.IsValid возвращает false. Почему? Что мне не хватает?

Спасибо

ПРИМЕЧАНИЕ. Я провел небольшой тест, и все данные извлекаются и привязываются, за исключением свойства bindedFilms. Пытался сделать это IEnumerable/List, но ничего из этого не работает. Функция .Any() всегда возвращает false

Разбейте его там, где вы проверяете IsValid, и посмотрите, какое свойство вызывает ошибку.

GH DevOps 20.02.2023 20:56

В настоящее время нет (я запустил тот же код, но без IsValid, и он работает), или вы имеете в виду присвоить ActorIdFk другое значение, например model.ActorId или id, и посмотреть, как это работает?

insolentmamba 20.02.2023 21:14

Если IsValid равно false, то где-то в ModelState есть свойство, вызывающее проблему.

GH DevOps 20.02.2023 21:53

Что определяет, когда это действительно или нет? Отсутствие нулей, когда свойство определено как не обнуляемое? Я думаю, что я, должно быть, неправильно привязываюсь, может быть, я посылаю что-то неправильное из представления,

insolentmamba 21.02.2023 01:18
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
Уроки CSS 6
Уроки CSS 6
Здравствуйте дорогие читатели, я Ферди Сефа Дюзгюн, сегодня мы продолжим с вами уроки css. Сегодня мы снова продолжим с так называемых классов.
Что такое Css? Для чего он используется?
Что такое Css? Для чего он используется?
CSS, или "Каскадные таблицы стилей", - это язык стилей, используемый в веб-страницах. CSS является одним из основных инструментов веб-разработки...
0
4
55
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Почему вы объявили bindedFilms как IQueryable? Это должен быть IEnumerable или список. Может быть, это проблема.

Все еще выясняю, когда лучше использовать IQueryable или IEnumerable. Список предназначен для отображения фильмографии актера посредством отложенного запроса в представлении, но эту часть я не показывал в вопросе, потому что проблема в привязке. В любом случае, свойство уже изменено на IEnumerable, и все же IsValid имеет значение false.

insolentmamba 20.02.2023 21:34

IQueryable подходит для запроса внешних ресурсов (например, базы данных). Вам необходимо объявить параметры API/метода как IEnumerable (стоит меньше) или List, но не IQueryable. В любом случае, не могли бы вы предоставить проект или необработанную html-форму, которую вы отправляете?

Kourosh 20.02.2023 21:59

Только что залил на гитхаб. Проблема в ActorsControllers и Actors/UpdateFilms.cshtml github.com/RascalSpark/FilmsWebApp/tree/master/FilmsWebApp

insolentmamba 21.02.2023 02:32

Спасибо за загрузку кода. Как упоминалось выше @Chen. недопустимое состояние вызывается свойством Actor.ActorName, которое помечено как [обязательное]. Решением будет любой из случаев, озвученных Ченом.

Kourosh 21.02.2023 13:49

Я думаю в этом проблема

<input type = "hidden" asp-for = "actor.ActorId" />

Похоже, вам нужно использовать @Model.ActorId. Пожалуйста, также убедитесь, что между сообщениями не указано значение параметра «Актер».

<input type = "hidden" asp-for = "@Model.actor.ActorId" /> <input type = "hidden" asp-for = "@Model.actor" /> <input type = "hidden" asp-for = "@Model.bindedFilms" /> Все еще IsValid возвращает false Актер не является нулевым, поскольку часть представления, которой я не делился, отображает свойства ViewModel и одно из свойств актеров (имя)

insolentmamba 21.02.2023 01:10
Ответ принят как подходящий

Проблема в том, что вы не привязываете соответствующее значение к @Model.actor.ActorName, из-за чего это свойство получает null в контроллере.

Вы можете добавить точку останова и посмотреть на свойство Values под ModelState, чтобы узнать, какое свойство модели является Invalid:

Есть два решения.

Первый, добавьте значение привязки к @Model.actor.ActorName в UpdateFilms.cshtml:

//...
<input type = "hidden" asp-for = "@Model.actor.ActorName" />
//...

Во-вторых, удалите атрибут [Required] и измените свойство ActorName в классе Actor, чтобы оно допускало значение NULL:

[DisplayName("Actor name")]
//[Required]
public string? ActorName { get; set; } = null!;

Это сработало! Просто знайте: в любом обычном случае, когда я передаю сложный тип (в данном случае объект «актер»), его свойства будут поставляться с привязанным объектом. Проблема заключалась в том, что одно из свойств актора в этом случае было помечено как обязательное, поэтому его нужно было явно отправить из формы, верно? Спасибо!

insolentmamba 21.02.2023 19:08

Да, если это свойство требуется, вам нужно присвоить ему значение, иначе оно будет иметь значение null и не пройдет проверку модели.

Chen 22.02.2023 01:58

Другие вопросы по теме