Ошибка в нескольких моделях при использовании в VIEW - PullRequest
0 голосов
/ 21 января 2019

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

Я создал класс ViewModel и его контроллер и импортировал модель для просмотра, но получил эту ошибку:

Элемент модели, переданный в словарь, имеет тип 'System.Collections.Generic.List`1 [LivrinhosMVC.Models.Category]', но это Для словаря требуется элемент модели типа 'LivrinhosMVC.Models.ViewModel'. **

Класс ViewModel:

public class ViewModel
        {
            public List<Category> Categories { get; set; }
            public List<Ad> Ads { get; set; }
        }

Контроллер ViewModel:

// GET: ViewModel
    public ActionResult Index()
    {
        ViewModel mymodel = new ViewModel();
        mymodel.Categories = db.Categories.ToList();
        mymodel.Ads = db.Ads.ToList();
        return View(mymodel);           
    }

Вид:

@model LivrinhosMVC.Models.ViewModel
<div class="container">
    <div class="row" style="margin:2em 0">
        <div class="col-sm-4">
            @Html.Label("Categorias")
            <table class="table-condensed">
                @foreach (var item in Model.Categories)
                {
                    <tr>
                        <td>@Html.ActionLink(item.Name, "../Category/Books", new { id = item.ID }, null)</td>
                    </tr>
                }
            </table>
        </div>
        <div class="col-sm-8" style="display:inline">
            @Html.TextBox("BookTitle", null, new { placeholder = "Título...", @class = "form-control" })
            @Html.DropDownList("Cities", "Portugal")
            @Html.ActionLink("Pesquisar", "Books", null, null, new { @class = "btn btn-primary" })

        </div>

        <div class="row">
            @foreach (var item in Model.Ads)
            {
            <div class="col-sm-3">
                @Html.Label(item.Title)
            </div>


            }
        </div>
    </div>
</div>

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Я не уверен, исходя из вашего примера кода, почему вы могли бы получить эту ошибку, похоже, есть проблема с @foreach (var item in Model.Categories).

Что я вижу и рекомендую, так это следоватьс подходом модели представления, но не присоединяйте объекты в модель представления.Модели представления должны быть простыми классами POCO, которые предоставляют достаточно деталей для представления, и ничего более.Причина этого заключается в том, чтобы помочь повысить производительность (меньше чтения и передачи данных) и повысить безопасность.(нет данных, отправленных клиенту, которых вы не ожидаете увидеть, например, представленных в инструментах отладки, и убедитесь, что объекты не отправляются обратно на сервер с непреднамеренным редактированием, снова через инструменты отладки, доверенные, подключенные и зафиксированные вконтекст.)

Я бы предложил создать CategorySummaryViewModel и AdSummaryViewModel, содержащие только идентификатор и имя для начала.Отметить все модели просмотра как Serializable.Затем, когда вы заполняете вашу ViewModel:

[Serializable]
public class AdsPageViewModel
{
  public List<CategorySummaryViewModel> Categories { get; set; } = new List<CategorySummaryViewModel>();
  public List<AdSummaryViewModel> Ads { get; set; } = new List<AdSummaryViewModel>();
}

public ActionResult Index()
{
  var mymodel = new AdsPageViewModel
  {
    Categories = db.Categories.Select(x=> new CategorySummaryViewModel
    {
      Id = x.Id,
      Name = x.Name // Append other fields if necessary for the view.
    }).ToList(),
    Ads = db.Ads.Select(x => new AdSummaryViewModel
    {
      Id = x.Id,
      Name = x.Name
    }).ToList()
  };
  return View(mymodel);           
}

Это будет казаться большим количеством кода / усилий, чем просто передача сущностей.Вы можете использовать такой инструмент, как Automapper, чтобы упростить это, и использовать .ProjectTo<T>, чтобы получить те же преимущества, что и выше.Эти преимущества включают в себя то, что при использовании .Select() оператор EF SQL отправляется в базу данных, а данные, возвращаемые из базы данных, включают только те поля, которые нужны нашей модели представления.Меньше данных по проводам = быстрее и меньше памяти требуется на сервере приложений и клиенте для запроса.Это также гарантирует, что наше представление может видеть только те поля, которые мы хотим видеть.Кто-то, использующий F12 в нашем клиенте, не может проверить другие FK и поля, которые скрыты только потому, что у нас нет элементов управления, видимых на странице.Мы также гарантируем, что наше приложение не принимает объекты обратно от клиента, где будет соблазн присоединить их к контексту и сохранить их.(кажется простым, но уязвимым для хакеров, изменяющих данные сущности с помощью тех же инструментов отладки и повреждающих сохраненные данные.)

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

0 голосов
/ 21 января 2019

Попробуйте с нетерпением загрузить данные , которые вы хотите отправить в представление.

Например:

public ActionResult Index()
{
    var model = db.ViewModel
        .Include(c => c.Categories);
        .Include(c => c.Ads);

    return View(model.ToList());
}

И сделать вид Strogly набранным как:

@model IEnumerable<LivrinhosMVC.Models.ViewModel>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...