Как заполнить Select taghelper в Razor, используя данные из таблицы базы данных SQL

Я использую ASP.NET Core 1.0 и EF Core 1.0, и в моей базе данных SQL есть следующий класс code-first.

namespace GigHub.Models
{
  public class Genre
  {
    public byte Id { get; set; }

    [Required]
    [StringLength(255)]
    public string Name { get; set; }
  }
}

У меня также есть следующий класс ViewModel, который я использую в форме представления Razor:

namespace GigHub.ViewModels
{
  public class GigFormViewModel
  {
    public string Venue { get; set; }
    public string Date { get; set; }
    public string Time { get; set; }
    public List<Genre> Genres { get; set; }
  }
}

Еще у меня есть такой контроллер:

using GigHub.Data;
using GigHub.ViewModels;
using Microsoft.AspNetCore.Mvc;

namespace GigHub.Controllers
{
  public class GigsController : Controller
  {
    private readonly ApplicationDbContext _context;

    public GigsController(ApplicationDbContext context)
    {
      _context = context;
    }
    public IActionResult Create()
    {
      var vm = new GigFormViewModel();

      // Need to get my Genre list from the DbSet<Genre> in my database context injected above
      // into the GigFormViewModel for the Select taghelper to consume

      return View(vm);
    }
  }
}

У меня есть представление Razor, настроенное на использование ViewModel, но я не уверен, как следует настроить приведенный ниже код Select taghelper для доступа к свойству Genre.

    <div class="form-group">
      <label asp-for="????" class="col-md-2 control-label"></label>
      <div class="col-md-10">
        <select asp-for="????" asp-items="????" class="form-control"></select>
        <span asp-validation-for="????" class="text-danger" />
      </div>
    </div>

У меня в основном проблемы с поиском того, как получить мой список жанров из моей базы данных в свойстве ViewModel в форме, которую может использовать Select taghelper asp-items =. Многочисленные искажения методом проб и ошибок, через которые я прошел, обычно приводят к проблемам с преобразованием общего типа List ‹> в тип SelectListItem MVC. Я подозреваю, что мой класс ViewModel Genre нуждается в корректировке, но мои исследования до сих пор привели только к статьям, охватывающим предыдущие версии ASP.NET и Entity Framework, и мне трудно сопоставить их с ядром ASP.NET 1.0 RC2 и EF Core 1.0.


person Darren Evans    schedule 27.07.2016    source источник
comment
Нет ли способа избежать ViewBag и получить список из ViewModel в форме списка для taghelper по строкам asp-items = Model.MyGenreListHere? Это где я ошибаюсь?   -  person Darren Evans    schedule 27.07.2016
comment
Просто используйте поле в вашей ViewModel. Я отправлю пример из документации ASP.NET.   -  person Reza Aghaei    schedule 27.07.2016
comment
Я подозреваю, что моя основная проблема переходит из List ‹Genre› из моего свойства ViewModel в что-то вроде IEnumerable ‹SelectListItem›, но синтаксис ускользает от меня. Мне еще многое предстоит узнать о C #.   -  person Darren Evans    schedule 27.07.2016


Ответы (1)


Вы можете использовать asp-for, чтобы указать имя свойства модели для элемента select, и asp-items, чтобы указать элементы option.

<select asp-for="SomeFiles" asp-items="Model.SomeOptions"></select> 

Вы также можете использовать ViewBag.SomeOptions, если не хотите добавлять поле SomeOptions в режим.

Для получения дополнительной информации см. Документация Select Tag Helper.

Пример

Просмотр

<select asp-for="Country" asp-items="Model.Countries"></select> 

Модель

using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace FormsTagHelper.ViewModels
{
    public class CountryViewModel
    {
        public string Country { get; set; }

        public List<SelectListItem> Countries { get; set; }
    }
}

Контроллер

Метод Index инициализирует CountryViewModel, устанавливает выбранную страну и список стран и передает модель в представление индекса.

public IActionResult Index()
{
    var model = new CountryViewModel();
    model.Country = "CA";
    model.Countries = db.Countries
                        .Select(x => new SelectListItem { Value = x.Id, Text = x.Name })
                        .ToList();

    return View(model);
}
person Reza Aghaei    schedule 27.07.2016
comment
Я тоже просматривал этот пример на сайте документации, но не мог мысленно сопоставить его со своей ситуацией. У меня уже есть список жанров, хранящийся в моей модели предметной области в базе данных, поэтому в моей модели представления не должно быть необходимости инициализировать эти элементы путем их «создания» для использования в taghelper. Я надеялся, что мой контроллер каким-то образом использует контекст моей базы данных для чтения значений из моего DbContext ‹Genre› и сопоставления их со свойством в моей ViewModel, но синтаксис, позволяющий избежать проблем с преобразованием, ускользает от меня. - person Darren Evans; 27.07.2016
comment
Проверьте отредактированный ответ. Вы можете просто преобразовать данные таблицы в List<SelectListItem>, как в примере выше. - person Reza Aghaei; 27.07.2016
comment
Большой. Кажется, это сработало и вернуло меня в нужное русло. Похоже, мой Linq-Fu мог бы быть лучше. Кажется, мне нужно найти еще несколько руководств по Linq, чтобы заполнить пробелы в моих знаниях. Большое спасибо. - person Darren Evans; 27.07.2016
comment
Странно то, что я предположил, что Select taghelper действует как раскрывающийся список, но обработанный HTML показывает уже расширенный список записей из моей базы данных. Ничего страшного, проблема с царапинами в голове решена, и мне просто нужно освежить в памяти поведение taghelper, чтобы оно работало как выпадающее :) - person Darren Evans; 27.07.2016
comment
Насколько я знаю, это эквивалент Html.DropDownListFor. Но у меня нет среды, чтобы проверить это сам. - person Reza Aghaei; 27.07.2016