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

如何从JS视图向ASP.NET MVC Action传递多选列表数据

ASP.NET MVC前端选中列表数据传递为空问题修复

问题背景

在ASP.NET MVC项目中,通过前端JS维护选中的作者、出版社、译者列表(已实现重复项校验、删除后可重新添加功能),尝试通过隐藏输入框将数据传递到后端Create Action,但后端始终接收为空值。

问题原因分析

  1. Form字段大小写不匹配:后端获取表单数据时使用Request.Form["selectedAuthors"](小写开头),而前端隐藏输入框的name属性是SelectedAuthors(大写S),ASP.NET表单字段名区分大小写,导致无法获取值。
  2. JS变量遮蔽问题:updateHiddenFields函数内重新声明了与全局变量同名的局部变量,导致全局数组的内容没有被正确拼接赋值给隐藏输入框。
  3. 删除操作的数组更新失效:删除按钮的事件处理中,修改的是局部的selectedItemList变量,没有同步更新全局数组,导致隐藏输入框的值无法正确反映最新选中状态。

修复方案

1. 后端代码修改

修正Form字段名大小写,与前端保持一致,同时优化空值处理逻辑:

[HttpPost]
public async Task<ActionResult> Create(CreateBookViewModel model)
{
    var bookCategory = await _bookCategoryService.GetById(model.CategoryId);
    // 修正字段名大小写,与前端name属性一致
    var selectedAuthors = Request.Form["SelectedAuthors"].ToString();
    var selectedPublishers = Request.Form["SelectedPublishers"].ToString();
    var selectedTranslators = Request.Form["SelectedTranslators"].ToString();

    model.Category = bookCategory.Name;
    
    // 处理空字符串,避免Split产生空元素
    model.Authors = string.IsNullOrEmpty(selectedAuthors) 
        ? new List<string>() 
        : selectedAuthors.Split(',').ToList();
    model.Publishers = string.IsNullOrEmpty(selectedPublishers) 
        ? new List<string>() 
        : selectedPublishers.Split(',').ToList();
    model.Translators = string.IsNullOrEmpty(selectedTranslators) 
        ? new List<string>() 
        : selectedTranslators.Split(',').ToList();

    if (ModelState.IsValid)
    {
        var result = await _bookService.Create(model);
        if (result.IsSucceeded)
        {
            return RedirectToAction("Index", result);
        }
        else
        {
            ModelState.AddModelError(string.Empty, "خطا در ایجاد کتاب.");
        }
    }
    // 返回原视图保留用户输入,而非重定向清空内容
    return View(model);
}

2. HTML代码优化

确保所有表单元素包裹在<form>标签内,明确POST请求目标:

<form asp-action="Create" method="post">
    <div class="form-group">
        <label class="control-label">Authors:</label>
        <select class="form-control" id="authorInput" asp-items='new SelectList(Model.Authors,"Name")'>
            <option value="">Select Author</option>
        </select>
        <button type="button" id="addAuthorButton" class="btn btn-primary">Add</button>
        <ul id="selectedAuthorsList" class="list-group">
            <!-- 选中项将动态添加到这里 -->
        </ul>
        <span id="duplicateAuthorError" class="text-danger"></span>
    </div>

    <div class="form-group">
        <label class="control-label">Publishers:</label>
        <select class="form-control" id="publisherInput" asp-items='new SelectList(Model.Publishers,"Name")'>
            <option value="">Select Publisher</option>
        </select>
        <button type="button" id="addPublisherButton" class="btn btn-primary">Add</button>
        <ul id="selectedPublishersList" class="list-group">
            <!-- 选中项将动态添加到这里 -->
        </ul>
        <span id="duplicatePublisherError" class="text-danger"></span>
    </div>

    <div class="form-group">
        <label class="control-label">Translators:</label>
        <select class="form-control" id="translatorInput" asp-items='new SelectList(Model.Translators,"Name")'>
            <option value="">Select Translator</option>
        </select>
        <button type="button" id="addTranslatorButton" class="btn btn-primary">Add</button>
        <ul id="selectedTranslatorsList" class="list-group">
            <!-- 选中项将动态添加到这里 -->
        </ul>
        <span id="duplicateTranslatorError" class="text-danger"></span>
    </div>

    <input type="hidden" name="SelectedAuthors" id="SelectedAuthors" />
    <input type="hidden" name="SelectedPublishers" id="SelectedPublishers" />
    <input type="hidden" name="SelectedTranslators" id="SelectedTranslators" />

    <button type="submit" class="btn btn-primary">Save</button>
    <a class="btn btn-secondary" asp-action="Index">Back To Book List</a>
</form>

3. JS代码修复

解决变量遮蔽和删除操作的数组同步问题:

var selectedAuthors = [];
var selectedTranslators = [];
var selectedPublishers = [];

function initializeSelectionLists() {
    selectedAuthors = [];
    selectedTranslators = [];
    selectedPublishers = [];
}

function isDuplicate(itemName, selectedItemList) {
    return selectedItemList.includes(itemName);
}

function addToSelectedList(inputId, listId, errorId, globalList) {
    var input = document.getElementById(inputId);
    var inputValue = input.value.trim();

    if (inputValue !== "") {
        if (!isDuplicate(inputValue, globalList)) {
            var selectedList = document.getElementById(listId);
            var listItem = document.createElement("li");
            listItem.className = "list-group-item";
            listItem.textContent = inputValue;

            var removeButton = document.createElement("button");
            removeButton.className = "btn btn-danger btn-sm float-left";
            removeButton.textContent = "Delete";
            // 直接操作全局数组,确保同步更新
            removeButton.onclick = function () {
                const index = globalList.indexOf(inputValue);
                if (index !== -1) {
                    globalList.splice(index, 1);
                }
                selectedList.removeChild(listItem);
                updateHiddenFields(); 
            };
            listItem.appendChild(removeButton);

            globalList.push(inputValue);
            selectedList.appendChild(listItem);
            input.value = ""; 
            document.getElementById(errorId).textContent = ""; 
            updateHiddenFields(); 
        } else {
            document.getElementById(errorId).textContent = "duplicate";
        }
    }
}

// 移除局部变量声明,直接使用全局数组拼接
function updateHiddenFields() {
    var authorsStr = selectedAuthors.join(",");
    var publishersStr = selectedPublishers.join(",");
    var translatorsStr = selectedTranslators.join(",");

    console.log("SelectedAuthors: " + authorsStr);
    console.log("SelectedPublishers: " + publishersStr);
    console.log("SelectedTranslators: " + translatorsStr);

    document.getElementById("SelectedAuthors").value = authorsStr;
    document.getElementById("SelectedPublishers").value = publishersStr;
    document.getElementById("SelectedTranslators").value = translatorsStr;
}

// 绑定事件时传入对应全局数组
document.getElementById("addAuthorButton").addEventListener("click", function () {
    addToSelectedList("authorInput", "selectedAuthorsList", "duplicateAuthorError", selectedAuthors);
});

document.getElementById("addTranslatorButton").addEventListener("click", function () {
    addToSelectedList("translatorInput", "selectedTranslatorsList", "duplicateTranslatorError", selectedTranslators);
});

document.getElementById("addPublisherButton").addEventListener("click", function () {
    addToSelectedList("publisherInput", "selectedPublishersList", "duplicatePublisherError", selectedPublishers);
});

验证方法

  1. 打开浏览器开发者工具(F12),切换到Console标签页,添加/删除列表项时查看输出的字符串是否正确。
  2. 在后端Create Action中设置断点,查看Request.Form["SelectedAuthors"]等字段是否获取到正确的值。
  3. 提交表单后,检查ViewModel中的Authors、Publishers、Translators属性是否正确赋值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 18:15:55