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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:55:22