You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 3.1 Razor Pages如何实现SQL Server绑定下拉列表

ASP.NET Core 3.1 Razor Pages 实现City字段下拉列表(从SQL Server加载选项)

以下实现全为Razor Pages原生写法,无MVC相关逻辑:

  • 第一步:准备城市选项数据源
    两种方案二选一即可:

    1. 单独维护城市选项表(推荐,方便统一管理可选值)
      在Models目录下新增城市选项实体:
    using System.ComponentModel.DataAnnotations;
    
    public class CityOption
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string CityName { get; set; }
    }
    

    在你项目的EF Core DbContext类中新增对应DbSet配置:

    public DbSet<CityOption> CityOptions { get; set; }
    

    打开包管理器控制台执行迁移命令,更新本地SQL Server数据库生成表结构,之后手动在表中录入所有可选城市数据即可:

    Add-Migration AddCityOptionTable
    Update-Database
    
    1. 从已有Person表去重取城市值(无需新建表,适合不需要单独维护选项的场景)
      不需要新增实体和表,后续查询时直接从Persons表去重取已录入的城市值作为选项即可。
  • 第二步:修改新增页面(Create)的后置代码Create.cshtml.cs
    注入DbContext,新增下拉列表绑定属性,在页面加载、校验失败返回时加载城市选项:

    using Microsoft.AspNetCore.Mvc.Rendering;
    using Microsoft.EntityFrameworkCore;
    // 保留原有using引用
    
    public class CreateModel : PageModel
    {
        private readonly YourAppDbContext _context; // 替换为你项目中实际的DbContext类名
        
        public CreateModel(YourAppDbContext context)
        {
            _context = context;
        }
    
        [BindProperty]
        public Person Person { get; set; }
        // 存储下拉选项的属性
        public SelectList CitySelectList { get; set; }
    
        public async Task<IActionResult> OnGetAsync()
        {
            // 加载城市选项
            await LoadCityOptions();
            return Page();
        }
    
        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                // 校验失败返回页面时必须重新加载选项,否则下拉框为空
                await LoadCityOptions();
                return Page();
            }
    
            _context.Persons.Add(Person);
            await _context.SaveChangesAsync();
            return RedirectToPage("./Index");
        }
    
        // 抽离公共的城市选项加载逻辑,避免重复写代码
        private async Task LoadCityOptions(string selectedCity = null)
        {
            List<string> cityList;
            // 单独表方案用下面这段查询
            cityList = await _context.CityOptions
                .OrderBy(c => c.CityName)
                .Select(c => c.CityName)
                .ToListAsync();
            // 如果用Person表去重方案,注释上面的查询,改用下面这段
            // cityList = await _context.Persons
            //     .Where(p => !string.IsNullOrEmpty(p.City))
            //     .Select(p => p.City)
            //     .Distinct()
            //     .OrderBy(c => c)
            //     .ToListAsync();
    
            CitySelectList = new SelectList(cityList, selectedCity);
        }
    }
    
  • 第三步:修改Create.cshtml页面的City字段,替换原文本输入框为下拉框
    把原有City字段的<input>标签替换为<select>标签,使用内置的select tag helper绑定选项:

    <div class="form-group">
        <label asp-for="Person.City" class="control-label"></label>
        <select asp-for="Person.City" class="form-control" asp-items="Model.CitySelectList">
            <option value="">--请选择城市--</option>
        </select>
        <span asp-validation-for="Person.City" class="text-danger"></span>
    </div>
    
  • 第四步:修改编辑页面(Edit)的后置代码Edit.cshtml.cs
    逻辑和新增页一致,加载选项时传入当前Person已绑定的City值作为默认选中项:

    using Microsoft.AspNetCore.Mvc.Rendering;
    using Microsoft.EntityFrameworkCore;
    // 保留原有using引用
    
    public class EditModel : PageModel
    {
        private readonly YourAppDbContext _context; // 替换为你项目中实际的DbContext类名
        
        public EditModel(YourAppDbContext context)
        {
            _context = context;
        }
    
        [BindProperty]
        public Person Person { get; set; }
        public SelectList CitySelectList { get; set; }
    
        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if (id == null) return NotFound();
            Person = await _context.Persons.FirstOrDefaultAsync(m => m.ID == id);
            if (Person == null) return NotFound();
            
            // 加载城市选项,传入当前人员的城市作为默认选中值
            await LoadCityOptions(Person.City);
            return Page();
        }
    
        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                await LoadCityOptions(Person.City);
                return Page();
            }
    
            _context.Attach(Person).State = EntityState.Modified;
            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!PersonExists(Person.ID)) return NotFound();
                throw;
            }
            return RedirectToPage("./Index");
        }
    
        private bool PersonExists(int id)
        {
            return _context.Persons.Any(e => e.ID == id);
        }
    
        // 和新增页共用相同的选项加载逻辑
        private async Task LoadCityOptions(string selectedCity = null)
        {
            List<string> cityList;
            // 单独表方案
            cityList = await _context.CityOptions
                .OrderBy(c => c.CityName)
                .Select(c => c.CityName)
                .ToListAsync();
            // Person表去重方案用这段
            // cityList = await _context.Persons
            //     .Where(p => !string.IsNullOrEmpty(p.City))
            //     .Select(p => p.City)
            //     .Distinct()
            //     .OrderBy(c => c)
            //     .ToListAsync();
    
            CitySelectList = new SelectList(cityList, selectedCity);
        }
    }
    
  • 第五步:修改Edit.cshtml页面的City字段,和新增页替换逻辑一致
    把原有文本输入框替换为下拉框:

    <div class="form-group">
        <label asp-for="Person.City" class="control-label"></label>
        <select asp-for="Person.City" class="form-control" asp-items="Model.CitySelectList">
            <option value="">--请选择城市--</option>
        </select>
        <span asp-validation-for="Person.City" class="text-danger"></span>
    </div>
    

补充说明:如果需要强制用户选择城市,可以在Person类的City属性上添加[Required(ErrorMessage = "请选择城市")]校验特性,表单提交时会自动触发非空校验。

内容的提问来源于stack exchange,提问作者wiedersehen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:30:51