Как правило, лучший способ - установить его на модель представления. Другими словами, добавьте свойства, такие как:
public IEnumerable<SelectListItem> BrandOptions { get; set; }
Затем в вашем контроллере добавьте приватный метод для заполнения этих списков опций:
private Task PopulateOptionsAsync(CarQuote model)
{
model.BrandOptions = await _context.Brands.Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.Name
}).ToListAsync();
// etc
}
Затем вызовите это в своем действии, прежде чем вернуть модель в представление. Лучше всего это использовать как частный метод, так как тогда вы можете поделиться им между GET и POST-версиями вашего действия. Тогда, наконец, на ваш взгляд:
<select asp-for="Brand" asp-items="@Model.BrandOptions"></select>
Альтернативный подход - использовать внедрение представления с пользовательским сервисом. Мне лично не нравится добавлять такую логику в представление, но Microsoft действительно представляет ее в качестве возможного варианта. По сути, вы просто создаете класс обслуживания, в котором есть методы для возврата ваших опций:
public class CarQuoteOptionsService
{
private readonly ModelsContext _context;
public CarQuoteOptionsService(ModelsContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public Task<List<SelectListItem>> GetBrandOptionsAsync =>
_context.Brands.Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.Name
}).ToListAsync();
// etc
}
Затем зарегистрируйте это в ConfigureServices
:
services.AddScoped<CarQuoteOptionsService>();
Наконец, введите его в свой контроллер и используйте его по желанию:
@inject CarQuoteOptionsService OptionsService
...
<select asp-for="Brand" asp-items="@(await OptionsService.GetBrandOptionsAsync())"></select>