.NET Core MVC拖拽元素后向控制器传值的最优实现方案
最优实现方案:拖拽选择城市后传递至.NET Core MVC控制器
直接用隐藏输入框绑定模型字段是最简洁高效的方案,完全契合.NET Core MVC的模型绑定机制,比填充下拉框或手动赋值更直观且不易出错。以下是具体实现步骤:
1. 定义视图模型
先创建对应表单数据的ViewModel,包含出发/到达城市ID、出发日期等字段:
public class TripViewModel { // 出发城市ID(建议用ID而非名称,避免重复或编码问题) public int DepartureCityId { get; set; } // 到达城市ID public int ArrivalCityId { get; set; } // 出发日期 [DataType(DataType.Date)] public DateTime DepartureDate { get; set; } // 用于渲染城市网格的列表(可选) public List<City> Cities { get; set; } } // 城市实体类示例 public class City { public int Id { get; set; } public string Name { get; set; } public string ImageUrl { get; set; } }
2. 构建Razor视图
在视图中添加表单、拖拽目标区域、隐藏输入框(用asp-for绑定ViewModel字段),以及城市图片网格:
@model TripViewModel <form asp-action="BookTrip" method="post"> <!-- 出发城市拖拽目标区 --> <div class="drop-zone p-3 border border-secondary rounded mb-3" id="departure-zone"> <h5>出发</h5> <div id="selected-departure" class="mt-2"></div> <!-- 绑定DepartureCityId的隐藏输入框,提交时自动传递到控制器 --> <input type="hidden" asp-for="DepartureCityId" id="departure-city-id" /> </div> <!-- 到达城市拖拽目标区 --> <div class="drop-zone p-3 border border-secondary rounded mb-3" id="arrival-zone"> <h5>到达</h5> <div id="selected-arrival" class="mt-2"></div> <input type="hidden" asp-for="ArrivalCityId" id="arrival-city-id" /> </div> <!-- 出发日期选择框 --> <div class="mb-3"> <label asp-for="DepartureDate" class="form-label"></label> <input asp-for="DepartureDate" class="form-control" /> <span asp-validation-for="DepartureDate" class="text-danger"></span> </div> <button type="submit" class="btn btn-primary">提交行程</button> </form> <!-- 城市图片网格 --> <div class="row mt-4"> @foreach (var city in Model.Cities) { <div class="col-3 mb-3 city-item" data-city-id="@city.Id" data-city-name="@city.Name" style="cursor:move;"> <img src="@city.ImageUrl" alt="@city.Name" class="img-fluid rounded" /> <p class="text-center mt-1">@city.Name</p> </div> } </div>
3. 完善jQuery UI拖拽逻辑
修改拖拽/放置事件,将选中城市的ID赋值给对应的隐藏输入框,同时在页面显示选中的城市信息:
$(function() { // 初始化城市项为可拖拽元素 $(".city-item").draggable({ revert: "invalid", // 拖到非目标区时返回原位置 helper: "clone" // 拖拽时显示克隆元素,避免原元素被移走 }); // 出发区域放置逻辑 $("#departure-zone").droppable({ accept: ".city-item", drop: function(event, ui) { var cityId = ui.draggable.data("city-id"); var cityName = ui.draggable.data("city-name"); var cityImg = ui.draggable.find("img").attr("src"); // 赋值给绑定模型的隐藏输入框 $("#departure-city-id").val(cityId); // 在页面展示选中的城市 $("#selected-departure").html(` <img src="${cityImg}" alt="${cityName}" style="width:60px; height:auto;" /> <span class="ms-2">${cityName}</span> `); } }); // 到达区域放置逻辑 $("#arrival-zone").droppable({ accept: ".city-item", drop: function(event, ui) { var cityId = ui.draggable.data("city-id"); var cityName = ui.draggable.data("city-name"); var cityImg = ui.draggable.find("img").attr("src"); $("#arrival-city-id").val(cityId); $("#selected-arrival").html(` <img src="${cityImg}" alt="${cityName}" style="width:60px; height:auto;" /> <span class="ms-2">${cityName}</span> `); } }); });
4. 控制器接收参数
控制器的Post方法直接接收TripViewModel参数,模型绑定会自动将表单字段(包括隐藏输入框的值)映射到模型属性:
public class TripController : Controller { private readonly ICityService _cityService; // 依赖注入城市服务(假设用于获取城市列表) public TripController(ICityService cityService) { _cityService = cityService; } // 显示表单页面 public IActionResult Index() { var model = new TripViewModel { Cities = _cityService.GetAllCities() }; return View(model); } // 处理表单提交 [HttpPost] public IActionResult BookTrip(TripViewModel model) { if (ModelState.IsValid) { // 这里处理业务逻辑,比如保存行程到数据库 return RedirectToAction("TripSuccess"); } // 验证失败时,重新加载城市列表并返回表单页面 model.Cities = _cityService.GetAllCities(); return View("Index", model); } public IActionResult TripSuccess() { return View(); } }
方案对比与优势
- 对比填充下拉框方案:不需要维护下拉框和拖拽值的同步逻辑,避免了用户误操作下拉框导致值不一致的问题,界面更简洁。
- 对比手动赋值模型方案:利用MVC原生的模型绑定机制,无需通过AJAX提前传递值,减少前端后端的交互成本,代码更符合MVC设计模式。
- 隐藏输入框不会干扰用户操作,仅在表单提交时传递必要数据,兼顾用户体验和后端接收的便捷性。
内容的提问来源于stack exchange,提问作者StijnT
相关产品推荐
相关产品推荐

