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

ASP.NET MVC级联下拉框选项显示undefined问题求助

级联下拉框选项显示undefined问题修复

问题场景

在表单中实现位置-房间二级联动下拉:

  • 位置下拉框选中项变化时,通过ajax请求后端接口拉取对应位置的房间列表
  • 接口可正常返回预期数量的选项数据,但渲染后所有选项文本显示为undefined

原视图核心代码

<div class="form-group row">
    <div class="col-4">
        <label asp-for="job.LocationId"></label>
    </div>
    <div class="col-8">
        <select asp-for="job.LocationId" id="LocationId" name="LocationId" 
            asp-items="@Model.LocationList" class="form-select">
            <option disabled selected>--Select Location--</option>
        </select>
    </div>
</div>
<div class="form-group row">
    <div class="col-4">
        <label asp-for="job.RoomId"></label>
    </div>
    <div class="col-8">
        <select id="RoomId" name="RoomId" asp-for="job.RoomId" 
            asp-items="@(new SelectList(string.Empty, "Value", "Text"))" class="form-select">
        </select>
    </div>
</div>

原前端联动JS代码

<script>
$(document).ready(function () {
    $('#LocationId').change(function () {
        $("#RoomId").empty();  
        $.ajax({  
            type: 'GET',  
            url: '@Url.Action("GetRooms")',
            dataType: 'json',   
            data: { locationId: $('#LocationId Option:Selected').val() },
            success: function (rooms) {  
                $.each(rooms, function (i, room) {  
                    $("#RoomId").append('<option value="' + room.Value  + '">' +    
                         room.Text  + '</option>');                        
                });  
            },  
            error: function (ex) {  
                alert('Failed to retrieve rooms.' + ex);  
            }  
        });  
        return false;  
    })
});
</script>

原后端接口代码

[HttpGet]
public JsonResult GetRooms(string locationId)
{
    int.TryParse(locationId, out int LocID);
    
    List<SelectListItem> rooms = new List<SelectListItem>();
    rooms.Add(new SelectListItem { Text = "-- Select Room --", Value = "0" });
    IEnumerable<Room> roomList = _unitOfWork.Room.GetAll(r => r.LocationId == LocID);
    foreach (Room room in roomList)
    {
        rooms.Add(new SelectListItem { Text = room.RoomName, Value = room.Id.ToString() });
    }

    var list = Json(new SelectList(rooms, "Value", "Text"));
    return Json(new SelectList(rooms, "Value", "Text"));
}

问题根因

ASP.NET Core 默认的JSON序列化规则会将C#端的帕斯卡命名(首字母大写,如Text/Value)自动转换为驼峰命名(首字母小写,如text/value)返回给前端。前端代码中读取的是大写开头的room.Value、room.Text,实际返回的JSON对象中不存在这两个属性,取值为undefined,最终渲染出的选项文本就显示为undefined。

另外原代码中存在两处冗余/不规范点:

  • 后端接口中定义了未使用的变量list,属于冗余代码
  • 前端选择选中项的选择器写为Option:Selected,不符合jQuery选择器规范,应写为小写的option:selected

修复方案

二选一即可,推荐优先选方案1,改动量最小。

方案1:修改前端JS属性读取逻辑

将success回调中读取选项属性的代码改为读取小写开头的属性即可,修正后的JS代码:

<script>
$(document).ready(function () {
    $('#LocationId').change(function () {
        $("#RoomId").empty();  
        $.ajax({  
            type: 'GET',  
            url: '@Url.Action("GetRooms")',
            dataType: 'json',   
            data: { locationId: $('#LocationId option:selected').val() },
            success: function (rooms) {  
                $.each(rooms, function (i, room) {  
                    // 改为读取小写开头的value、text属性
                    $("#RoomId").append('<option value="' + room.value  + '">' +    
                         room.text  + '</option>');                        
                });
                // 可选:加载完成后默认选中第一个提示项
                $("#RoomId").val("0");
            },  
            error: function (ex) {  
                alert('获取房间列表失败:' + ex.responseText);  
            }  
        });  
        return false;  
    })
});
</script>

方案2:修改后端返回逻辑,避免序列化命名问题

后端不需要将列表二次包装为SelectList类型,直接返回构造好的简单对象列表即可,同时删除冗余代码,修正后的接口代码:

[HttpGet]
public JsonResult GetRooms(string locationId)
{
    int.TryParse(locationId, out int LocID);
    
    List<object> rooms = new List<object>
    {
        new { Text = "-- Select Room --", Value = "0" }
    };
    IEnumerable<Room> roomList = _unitOfWork.Room.GetAll(r => r.LocationId == LocID);
    foreach (Room room in roomList)
    {
        rooms.Add(new { Text = room.RoomName, Value = room.Id.ToString() });
    }
    // 直接返回列表,删除冗余的SelectList包装和无用变量
    return Json(rooms);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:39:21