ASP.NET MVC 如何将配置文件的评级列表传入动态创建的ViewModel
实现方案
推荐以下两种实现方式,按优先级从高到低排序:
方案1:依赖注入+视图注入(最优)
该方案无需在ViewModel中维护重复的下拉列表属性,从根源避免新增条目时列表丢失的问题,完全符合关注点分离原则。
步骤1:注册评级列表为全局单例
在Program.cs启动文件中加载配置并注册单例,仅在程序启动时读取一次配置,后续全局复用:
var builder = WebApplication.CreateBuilder(args); // 加载电影评级配置 var movieStandards = builder.Configuration.GetSection("Standards:MovieStandards").Get<List<string>>(); var movieRatingSelectList = movieStandards.Select(x => new SelectListItem { Text = x, Value = x }).ToList(); // 注册为单例服务 builder.Services.AddSingleton(movieRatingSelectList); // 其余服务注册逻辑...
步骤2:移除ViewModel中的冗余属性
删除MovieAddViewModel中的RatingList属性,避免每个实例重复存储相同的列表数据:
public class MovieAddViewModel { [Display(Name = "Movie Title")] public string Name { get; set; } [Display(Name = "Rating")] public string Rating { get; set; } // 移除public List<SelectListItem> RatingList { get; set; } }
步骤3:视图中注入评级列表
在电影条目的分部视图(_Movie.cshtml)顶部注入全局的评级列表服务,直接用于下拉框渲染:
@inject List<SelectListItem> MovieRatingList @model MyProject.Models.ViewModels.MovieAddViewModel <tr> <td> <input asp-for="Id" class="form-control" /> </td> <td> <select asp-for="Rating" asp-items="MovieRatingList" class="form-control"></select> </td> <td> <input type="button" onclick="Remove(this)" id="removeMovie_@Model.Uid" class="btn" value="Remove" /> </td> </tr>
方案2:控制器注入后赋值
如果希望保留ViewModel中的RatingList属性,可通过控制器注入单例列表,每次新增/回发时统一赋值:
步骤1:同方案1,先注册评级列表为单例
步骤2:控制器注入列表并赋值
修改MovieController代码,通过构造函数注入单例列表,在返回视图前为所有电影条目赋值RatingList:
public class MovieController : Controller { private readonly List<SelectListItem> _movieRatingList; // 构造函数注入单例评级列表 public MovieController(List<SelectListItem> movieRatingList) { _movieRatingList = movieRatingList; } // Create页面初始化GET方法 public IActionResult Create() { var vm = new ShelfAddViewModel { Movies = new List<MovieAddViewModel> { new MovieAddViewModel { RatingList = _movieRatingList } } }; return View(vm); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult AddMovie([Bind("Id,Movie")] ShelfAddViewModel shelf) { // 为已有条目补全列表(避免回发后丢失) foreach(var movie in shelf.Movies) { movie.RatingList = _movieRatingList; } // 新增条目赋值列表 shelf.Movies.Add(new MovieAddViewModel { RatingList = _movieRatingList }); return PartialView("_Movie", shelf); } }
内容的提问来源于stack exchange,提问作者jimbo
相关产品推荐
相关产品推荐

