c# mvc: сохранение данных из представления в контроллер, а затем через один объект для List‹ViewModel›

Я работаю с View, который возвращает List<ViewModel> в метод действия Create Controller.

Вопросы:

  1. Правильно ли вернуть List<ViewModel> контроллеру? Причина, по которой я это делаю, заключается в том, что мне нужно сделать несколько записей строк в БД для каждого пользователя. 2. Моя реализация Controller неверна, потому что я пытаюсь добавить данные через один пользовательский объект, где я получил список моделей представления, который является только представлением представления для одного пользователя. Так как же должен быть реализован контроллер?
  2. Нужно ли мне иметь метод public ActionResult Create() в контроллере?

Ограничения:

  1. Не могу изменить базу данных
  2. Ни одна из таблиц пользователей или ролей в базе данных не имеет типа int PK

Логика:

Пользователь сможет установить несколько флажков (представляет РОЛЬ) для каждого пользователя, и это должно быть сохранено в базе данных в виде одной строки. Например

введите описание изображения здесь

БД: таблица dbo.User должна иметь следующие записи при сохранении

(abcdefg, levelA, locationB, Role2, null, null, Y)

(msjdhcdu, levelA, locationB, Role2, null, null, Y) Тот же пользователь Другая роль

(msjdhcdu, levelA, locationB, Role3, null, null, Y) Тот же пользователь Другая роль

Пользователь будет оставаться на той же странице (сохранить VIEW) после нажатия кнопки «Сохранить» и отображения последних изменений в базе данных.

Модель представления:

public class UserViewModel
{
    public string UserName { get; set; }
    public string Level { get; set; }
    public string Location { get; set; }
    public List<RoleViewModel> Roles { get; set; }
}

public class RoleViewModel
{
    public string RoleName{ get; set; }
    public bool IsSelected { get; set; }
}

Представление: возможно, я делаю что-то очень неправильно в представлении.

@model List<Project.ViewModels.UserViewModel>

@using (@Html.BeginForm("Create", "User", FormMethod.Post ,new { id = "UserPermissionForm" }))


{
<table class="table">
    <tr>
        <th>User</th>
        @for (int i = 0; i < Model[0].Roles.Count; i++)
        {
            <th>
                @Model[0].Roles[i].RoleName
            </th>
        }
    </tr>
    @for (int i = 0; i < Model.Count; i++)
    {
        <tr>
            <td>
                @Html.HiddenFor(m => m[i].UserName)
                @Model[i].UserName
            </td>
            @for (int j = 0; j < Model[i].Roles.Count; j++)
            {
                <td>
                    @Html.CheckBoxFor(m => m[i].Roles[j].IsSelected)
                </td>
            }
        </tr>
    }
</table>

<div class="form-actions">
        <button type="submit" class="btn btn-success submit" value="Save">Save changes</button>
    </div>

<script>
    $('#Submit').click(function () {
        let url = '@Url.Action("Create", "Users")'
        $.post(url, $("#UserPermissionForm"))
        });
</script>

Контроллер:

[HttpPost]
    public ActionResult Create(List<UserViewModel> viewModelList)
    {
        for (int i= 0; i > viewModelList.Count; i++) {
            for (int j = 0; j > viewModelList[i].Roles.Count; j++) {

                    db.UserDetails.Add(new User 
                    {
                        username = viewModelList[i].UserName,
                        level = viewModelList[i].Level,
                        location = viewModelList[i].Location,
                        role = viewModelList[i].Roles[j].RoleName,
                        Approval = "",
                        Request = "",
                        Active = "Y"
                    });
            }

            db.SaveChanges();
            return RedirectToAction("Index","Users");
        }          
        return View(viewModelList); // not right
    }

Ошибка:

Элемент модели, переданный в словарь, имеет тип «System.Collections.Generic.List`1[Project.ViewModels.UserViewModel]», но для этого словаря требуется элемент модели типа «Project.Models.User».

Любое руководство/помощь приветствуется.

EDIT1: добавлено представление EDIT2: добавлена ​​бизнес-логика


person shaz    schedule 19.10.2016    source источник
comment
Пожалуйста, покажите свою страницу просмотра. где вы определяете@model   -  person Divyang Desai    schedule 19.10.2016
comment
Информация о странице ПРОСМОТР добавлена.   -  person shaz    schedule 19.10.2016
comment
@sharlene: это больше не имеет смысла, учитывая мнение, которое было добавлено к вопросу. Ошибка гласит, что представление ожидает модель типа Project.Models.User. Где конкретно эта ошибка происходит? Вы уверены, что это правильный взгляд?   -  person David    schedule 19.10.2016
comment
@David Да, это ВИД, на который я подаю в суд. Я предполагаю, что мой код javaScript в представлении неверен. Когда я отправляю по почте.   -  person shaz    schedule 19.10.2016
comment
@sharlene: Почему ты так предположил? Какое указание в вашей отладке на то, что JavaScript неверен? Эта ошибка возникает, когда контроллер передает в представление неправильную модель.   -  person David    schedule 19.10.2016
comment
@ Дэвид Скорее всего, потому что я новичок в этом и действительно не понимаю, где что-то идет не так. Только два места, где я передаю модель обратно в представление, — это мой метод Index() и метод Create(). Я обновлю сообщение своим методом Index(), если это даст представление о том, что я, вероятно, делаю неправильно.   -  person shaz    schedule 19.10.2016
comment
@ Дэвид Ты абсолютно прав. У меня есть автоматически сгенерированный VIEW для Create.cshtml, где @model Project.Models.User. Поскольку я не хочу использовать этот автоматически сгенерированный VIEW, должен ли я перенаправить его на VIEW, который я показал здесь/удалить этот автоматически сгенерированный VIEW?   -  person shaz    schedule 19.10.2016
comment
@sharlene: Ну, в общем, вы бы направляли пользователя к тому представлению, которое вы хотите, чтобы они видели, и вы бы предоставили этому представлению нужную ему модель. Варианты, которые у вас есть, остаются несколько похожими. Вы можете направить пользователя к другому представлению или изменить представление, к которому направляете пользователя, чтобы оно соответствовало потребностям системы.   -  person David    schedule 19.10.2016
comment
Давайте продолжим обсуждение в чате.   -  person shaz    schedule 19.10.2016


Ответы (1)


Здесь вы отправляете модель в представление:

return View(viewModelList);

И эта модель относится к типу List<UserViewModel>. Однако, согласно ошибке, представление ожидает модель типа User. Что-то вроде этого объявления в самом представлении:

@model Project.Models.User

Итак, у вас есть два варианта:

  1. Измените представление, чтобы принять модель типа List<UserViewModel>, внеся необходимые изменения в самом представлении, чтобы использовать этот новый тип модели.
  2. Отправьте в представление модель типа Project.Models.User (которая предположительно будет преобразованием одного элемента из List<UserViewModel>?).

На техническом уровне любой вариант вполне допустим. (Хотя эти два понятия взаимоисключающие, это либо одно, либо другое.) Вам решать, какой вариант имеет больше смысла для системы, которую вы строите, независимо от того, должно ли это представление работать с экземпляром или со списком.


Редактировать. Ваше изменение вопроса (включение представления), по-видимому, указывает на то, что вы, возможно, смотрите на неправильное представление. Представление, которое вы нам показываете, не соответствует сообщению об ошибке, которое вы нам показываете. Имейте в виду, что два пути выхода для вашего метода контроллера (перенаправление и возврат представления) вероятно вызывают разные представления.

В любом случае суть вопроса остается. Где-то вы предоставляете представление с типом, который отличается от ожидаемого. Возможно, вам придется выполнить дополнительную отладку, чтобы определить, где в вашем коде это происходит, но в конечном итоге проблема и возможное решение остаются такими же, как описано выше.

person David    schedule 19.10.2016
comment
Не могли бы вы включить все вопросы ОП. - person Divyang Desai; 19.10.2016
comment
@Div: Можно поконкретнее? Большая часть того, что задается в исходном вопросе, по-видимому, исходит из возникшей ошибки и указывает на некоторые непонимания со стороны ОП относительно взаимодействия контроллеров и представлений. Этот ответ пытается немного объяснить и упростить. Непонятно, что система должна делать на уровне бизнес-логики, поскольку мы ничего об этом не знаем. Но на техническом уровне этот ответ объясняет, что означает ошибка и как ее можно исправить. - person David; 19.10.2016
comment
Да, но посмотрите обновленный вопрос, OP определил ViewModel, а не класс Entity, на странице просмотра. - person Divyang Desai; 19.10.2016
comment
@Div: На данный момент я подозреваю, что ОП смотрит не на то. Тип, указанный в сообщении об ошибке, и тип, указанный в представлении, которое мы видим, не совпадают. - person David; 19.10.2016
comment
Да, это представление не вызовет никакой ошибки, о которой OP заявил в вопросе. - person Divyang Desai; 19.10.2016
comment
@David, я понимаю, что передаю не ту модель. Но моделью, на мой взгляд, является List‹UserViewModel›, но в контроллере я беру список и пытаюсь сохранить данные для каждого элемента в этом списке. Я не уверен, какой код неправильный. Просмотр или контроллер. Потому что я уже делаю то, что вы предложили. - person shaz; 19.10.2016
comment
@sharlene: Согласно сообщению об ошибке, которое вы видите, представление не ожидает модель типа List<UserViewModel>. Так что весьма вероятно, что вы смотрите здесь не на тот вид. Или, возможно, вы используете версию кода, которая не была обновлена. В любом случае сообщение об ошибке понятно. Где-то в представление передается неправильный тип. Если не здесь, то где-то еще. - person David; 19.10.2016