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

.NET6 MVC下拉框选值填充文本框遇JS错误及数据未定义问题

.NET6 MVC下拉框自动填充文本框问题排查与解决

问题描述

基于.NET6 MVC开发,在Create视图中实现下拉框选择客户后自动填充PrimaryContact、PrimaryEmail、CategoryID三个文本框功能时,遇到以下问题:

  • 运行时持续弹出JS错误弹窗
  • 调试初期出现404请求错误
  • 后续能看到数据传递,但访问data.PrimaryContact等属性时返回undefined

已核对页面元素ID与后端命名匹配,相关代码如下:

ViewModel代码

public class CreateReservationVM
{
    public Reservation Reservation { get; set; }
    public ClientDetailsVM ClientDetails { get; set; }
}

public class ClientDetailsVM
{
    public string PrimaryContact { get; set; }
    public string PrimaryEmail { get; set; }
    public int CategoryID { get; set; }
}

视图代码

<form asp-action="Create">
    <div class="row">
        <div class="col-md-4">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Reservation.ID" />
            <div class="form-group">
                <label asp-for="Reservation.CLientID" class="control-label"></label>
                <select asp-for="Reservation.CLientID" id="clientDropdown" class="form-control" asp-items="ViewBag.ClientList"></select>
            </div>
            <div id="clientDetails"></div>
            <input id="ClientDetails_PrimaryContact" asp-for="ClientDetails.PrimaryContact" />
            <input id="ClientDetails_PrimaryEmail" asp-for="ClientDetails.PrimaryEmail" />
            <input id="ClientDetails_CategoryID" asp-for="ClientDetails.CategoryID" />
            <div class="form-group">
                <label asp-for="Reservation.ReservationNumber" class="control-label"></label>
                <input asp-for="Reservation.ReservationNumber" class="form-control" />
                <span asp-validation-for="Reservation.ReservationNumber" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Reservation.Name" class="control-label"></label>
                <input asp-for="Reservation.Name" class="form-control" />
                <span asp-validation-for="Reservation.Name" class="text-danger"></span>
            </div>
        </div>
    </div>

    <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
    </div>
    <div>
        <a asp-action="Index">Back to List</a>
    </div>
</form>
@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
    <script src="~/js/getClientDetails.js" asp-append-version="true"></script>
}

JS脚本代码

$(document).ready(function () {
    var clientDropdown = $('#clientDropdown');

    clientDropdown.change(function () {
        var selectedClientID = $(this).val();

        $.ajax({
            url: '/Reservations/GetClientDetails',
            type: 'GET',
            data: { clientID: selectedClientID },
            dataType: 'json',
            success: function (data) {
                $('#clientDetails').html(data);
                $('#ClientDetails_PrimaryContact').val(data.PrimaryContact);
                $('#ClientDetails_PrimaryEmail').val(data.PrimaryEmail);
                $('#ClientDetails_CategoryID').val(data.CategoryID);
            },
            error: function () {
                alert('An error occurred while retrieving client details.');
            }
        });
    });
});

控制器代码

// GET: Reservations/Create
public IActionResult Create(int? clientID)
{
    List<Client> clients = _clientService.GetAllClients().ToList();
    ViewBag.ClientList = new SelectList(clients, "ID", "Name");

    Reservation reservation = new Reservation();
    ClientDetailsVM clientDetailsVM = null;

    if (clientID.HasValue)
    {
        var clientDetails = _clientService.GetClientByID(clientID.Value);
        clientDetailsVM = new ClientDetailsVM
        {
            PrimaryContact = clientDetails.PrimaryContact,
            PrimaryEmail = clientDetails.PrimaryEmail,
            CategoryID = clientDetails.CategoryID
        };
    }

    var viewModel = new CreateReservationVM
    {
        Reservation = reservation,
        ClientDetails = clientDetailsVM
    };

    return View("Create",viewModel);
}

[HttpGet]
public IActionResult GetClientDetails(int clientId)
{
    var clientDetails = _clientService.GetClientByID(clientId);

    if (clientDetails == null)
    {
        return NotFound();
    }

    var clientData = new
    {
        PrimaryContact = clientDetails.PrimaryContact,
        PrimaryEmail = clientDetails.PrimaryEmail,
        CategoryID = clientDetails.CategoryID
    };

    return Json(clientData);
}

问题原因

  1. URL硬编码导致404:直接使用'/Reservations/GetClientDetails'作为AJAX请求URL,若应用部署时有虚拟目录或路由配置变化,会导致请求路径错误。
  2. JSON对象错误用作HTML内容:成功回调中执行$('#clientDetails').html(data),将JSON对象直接插入DOM,会被转为[object Object]字符串,虽不直接导致属性undefined,但属于无效操作。
  3. 参数大小写不匹配:AJAX请求传递的参数是clientID(大写D),控制器方法接收参数为clientId(小写d),模型绑定存在大小写兼容隐患。
  4. 空值未处理:下拉框默认无选中值时,selectedClientID为空,发送请求后控制器接收int类型默认值0,若无对应ID的客户,返回NotFound()触发错误弹窗。

解决办法

1. 修正AJAX请求URL

使用MVC内置路由生成器生成正确URL,避免硬编码:

url: '@Url.Action("GetClientDetails", "Reservations")',

2. 移除无效的DOM插入操作

删除$('#clientDetails').html(data),该操作对填充文本框无意义。

3. 统一参数大小写

将AJAX请求的参数名改为clientId,与控制器参数保持一致:

data: { clientId: selectedClientID },

4. 添加空值判断

当下拉框未选择客户时,清空文本框并终止请求:

var selectedClientID = $(this).val();
// 清空文本框
$('#ClientDetails_PrimaryContact').val('');
$('#ClientDetails_PrimaryEmail').val('');
$('#ClientDetails_CategoryID').val('');

if (!selectedClientID) {
    return;
}

5. 优化错误处理

在错误回调中打印详细错误信息,便于调试:

error: function (xhr, status, error) {
    console.error('获取客户详情失败:', error);
    alert(`获取客户详情失败: ${error}`);
}

6. 增强控制器鲁棒性

添加参数空值判断,返回明确的错误信息:

[HttpGet]
public IActionResult GetClientDetails(int? clientId)
{
    if (!clientId.HasValue)
    {
        return BadRequest("客户ID不能为空");
    }

    var clientDetails = _clientService.GetClientByID(clientId.Value);

    if (clientDetails == null)
    {
        return NotFound("未找到指定客户");
    }

    var clientData = new
    {
        PrimaryContact = clientDetails.PrimaryContact,
        PrimaryEmail = clientDetails.PrimaryEmail,
        CategoryID = clientDetails.CategoryID
    };

    return Json(clientData);
}

7. 优化下拉框默认选项

添加默认空选项,提升用户体验:

<select asp-for="Reservation.CLientID" id="clientDropdown" class="form-control" asp-items="ViewBag.ClientList">
    <option value="">请选择客户</option>
</select>

最终修正后的JS脚本

$(document).ready(function () {
    var clientDropdown = $('#clientDropdown');

    clientDropdown.change(function () {
        var selectedClientID = $(this).val();
        // 清空文本框
        $('#ClientDetails_PrimaryContact').val('');
        $('#ClientDetails_PrimaryEmail').val('');
        $('#ClientDetails_CategoryID').val('');

        if (!selectedClientID) {
            return;
        }

        $.ajax({
            url: '@Url.Action("GetClientDetails", "Reservations")',
            type: 'GET',
            data: { clientId: selectedClientID },
            dataType: 'json',
            success: function (data) {
                $('#ClientDetails_PrimaryContact').val(data.PrimaryContact);
                $('#ClientDetails_PrimaryEmail').val(data.PrimaryEmail);
                $('#ClientDetails_CategoryID').val(data.CategoryID);
            },
            error: function (xhr, status, error) {
                console.error('获取客户详情失败:', error);
                alert(`获取客户详情失败: ${error}`);
            }
        });
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:15:35