在Netcore 2.0中使用Razor填充下拉列表

时间:2018-11-05 19:59:29

标签: c# asp.net razor asp.net-core-2.0 razor-pages

我对MVVC和netcore上的整个堆栈完全陌生。

我有一个具有文本输入的表单,还具有3个select下拉列表,需要填充这些下拉列表,以将信息保存在数据库的另一个表中。我被困在这个确切的部分,因为我不知道如何调用数据,然后将其放入选择中。表单的总体思路是,用户输入他的信息,然后从选择中选择一些数据,然后发送信息,然后将其保存在数据库的表中。

我目前有适用于我的汽车的表格表格

using System;
namespace forms.Models
{
    public class CarQuote
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Brand { get; set; }
        public string Model { get; set; }
        public string Year { get; set; }
        public string Version { get; set; }
        public string State { get; set; }
        public int ZipCode { get; set; }
    }
}

在我的UI中选择“品牌”,“型号”,“年份”和“版本”,这4个值需要填写,以从“汽车”表中获取信息,我创建了一个类来获取信息,但如果方法正确,我就不这样做。 / p>

using System;
namespace forms.Models
{
    public class Cars
    {
        public string Brand { get; set; }
        public string Model { get; set; }
        public string Version { get; set; }
        public string Year { get; set; }
    }
}

这也是我的“汽车报价”表单的Create.cshtml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using soofiforms.Models;

namespace forms.Pages.Car
{
    public class CreateModel : PageModel
    {
        private readonly soofiforms.Models.ModelContext _context;

        public CreateModel(soofiforms.Models.ModelContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public CarQuote CarQuote { get; set; }
        public Cars Cars { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.CarQuotes.Add(CarQuote);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

如何将我的Cars表连接到CarsQuote表单,以便可以填充我的选择?不便之处,谢谢您。

1 个答案:

答案 0 :(得分:2)

通常,最好的方法是在视图模型上进行设置。换句话说,添加以下属性:

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>