ASP.NET MVC单视图使用多模型时如何将表单数据传递到模型
表单数据传递方案与实现建议
一、@model dynamic 场景下的表单数据获取方法
你当前的表单存在基础问题:出发地、目的地的<select>标签未设置name属性,表单提交时不会携带这两个字段的值,需要先补全:
<!-- 出发地下拉框 --> <select class="form-control" name="fromAirport" id="fromAirport"> <!-- 目的地下拉框 --> <select class="form-control" name="toAirport" id="toAirport">
补全后控制器有两种方式接收表单数据:
- 直接在Action方法中声明对应参数,ASP.NET MVC默认模型绑定会自动匹配表单字段名给参数赋值:
[HttpPost] public IActionResult Search(string fromAirport, string toAirport, DateTime date, int passengers) { // 直接使用参数即可,可自行映射到你的业务模型 }
- 也可以通过
FormCollection接收所有表单值后再手动提取:
[HttpPost] public IActionResult Search(FormCollection form) { string from = form["fromAirport"]; string to = form["toAirport"]; DateTime date = DateTime.Parse(form["date"]); int count = int.Parse(form["passengers"]); // 后续业务逻辑 }
二、强烈建议改用自定义ViewModel方案
使用dynamic作为视图模型存在明显缺陷:无编译时类型检查、拼写错误只能在运行时发现、无IDE智能提示、后期维护成本高,而自定义ViewModel完全规避这些问题,实现成本也很低,步骤如下:
- 新建视图模型类
public class FlightSearchViewModel { // 用于渲染下拉选项的机场列表 public List<Airport> Airports { get; set; } // 表单提交字段 public string FromAirport { get; set; } public string ToAirport { get; set; } public DateTime Date { get; set; } public int Passengers { get; set; } }
- 修改视图声明与表单控件
将视图顶部的@model dynamic替换为强类型声明:
@using FlightBooker @model FlightSearchViewModel
表单控件可以直接用强类型绑定,无需手动写循环生成option:
<form asp-controller="Home" asp-action="Search" method="post"> <div class="form-group"> <label asp-for="FromAirport">出发地:</label> <select asp-for="FromAirport" class="form-control" asp-items="@new SelectList(Model.Airports, nameof(Airport.AirportCode), nameof(Airport.AirportCode))"> </select> </div> <div class="form-group"> <label asp-for="ToAirport">目的地:</label> <select asp-for="ToAirport" class="form-control" asp-items="@new SelectList(Model.Airports, nameof(Airport.AirportCode), nameof(Airport.AirportCode))"> </select> </div> <div class="form-group"> <label asp-for="Date">出发日期:</label> <input asp-for="Date" type="date" class="form-control"> </div> <div class="form-group"> <label asp-for="Passengers">乘客人数:</label> <select asp-for="Passengers" class="form-control"> <option>1</option> <option>2</option> <option>3</option> <option>4</option> </select> </div> <button type="submit" class="btn btn-primary mt-3">搜索航班</button> </form>
- 控制器逻辑适配
- GET请求的Index方法返回构造好的ViewModel:
public IActionResult Index() { var viewModel = new FlightSearchViewModel { Airports = // 你的机场列表查询逻辑 }; return View(viewModel); }
- POST请求的Search方法直接接收ViewModel参数,绑定逻辑由框架自动完成:
[HttpPost] public IActionResult Search(FlightSearchViewModel model) { // 直接使用model.FromAirport、model.ToAirport等属性即可 }
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

