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

JSON数据绑定DropdownList报错,问题在WebMethod还是前端处理?

问题描述

通过WebMethod生成了如下JSON数据:

[
  {
    "id": 367,
    "location": "Gagra"
  },
  {
    "id": 368,
    "location": "Gudauta"
  },
  {
    "id": 369,
    "location": "Sukhumi"
  },
  {
    "id": 370,
    "location": "Gulripshi"
  },
  {
    "id": 371,
    "location": "Ochamchira"
  },
  {
    "id": 372,
    "location": "Tkvarcheli"
  },
  {
    "id": 373,
    "location": "Gali"
  }
]

对应的WebMethod代码:

<WebMethod()>
Public Function PopulateStates(ByVal idLocation As Integer) As String
    Dim Locations As List(Of LocationData) = New List(Of LocationData)
    Dim JSONString As String
    Dim adp As New StatesTableAdapter
    Dim ds As StatesDataTable = adp.GetStatesByCountry(idLocation)
    If ds.Rows.Count > 0 Then
        For Each row As StatesRow In ds
            Dim ld As LocationData = New LocationData With {
                .id = row.idState,
                .location = row.locName
            }
            Locations.Add(ld)
        Next
    End If
    JSONString = JsonConvert.SerializeObject(Locations, Formatting.Indented)
    Return JSONString
End Function

Public Class LocationData
    Public Property id As Integer
    Public Property location As String
End Class

前端AJAX调用代码:

$('#ddlCountry').change(function (e) {
    $.ajax({
        type: "POST",
        url: "/TestWebService.asmx/PopulateStates",
        contentType: "application/json; charset=utf-8",
        data: '{"idLocation":"' + $(this).val() + '"}',
        dataType: "json",
        success: function (result, status, xhr) {
            console.log(result.d);
            $.each(result.d, function (key, value) {
                $("#ddlState").append($("<option></option>").val(value.id).html(value.location));
            });
        },
        error: function (xhr, status, error) {
            alert("Result: " + status + " " + error + " " + xhr.status + " " + xhr.statusText)
        }
    });
});

执行时出现错误:Uncaught TypeError: Cannot use 'in' operator to search for 'length' in [,请问问题出在WebMethod还是前端处理环节?

问题原因与解决方案

问题出在WebMethod和前端处理的双重问题,核心是JSON序列化重复:

  • WebMethod端问题:
    ASMX WebMethod默认会自动将返回对象序列化为JSON,但你手动用JsonConvert.SerializeObject把列表转成了JSON字符串,导致最终返回的是字符串形式的JSON,而非原生JSON对象。前端拿到的result.d是带格式的字符串,不是可直接遍历的数组。

  • 前端处理问题:
    直接用$.each遍历字符串,$.each要求遍历目标是数组或对象,字符串被当作普通文本处理时,就会触发in运算符查找length的错误。

修复方案

方案1:修改WebMethod,直接返回对象列表(推荐)

去掉手动序列化步骤,让WebMethod自动处理JSON转换:

<WebMethod()>
Public Function PopulateStates(ByVal idLocation As Integer) As List(Of LocationData)
    Dim Locations As List(Of LocationData) = New List(Of LocationData)
    Dim adp As New StatesTableAdapter
    Dim ds As StatesDataTable = adp.GetStatesByCountry(idLocation)
    If ds.Rows.Count > 0 Then
        For Each row As StatesRow In ds
            Dim ld As LocationData = New LocationData With {
                .id = row.idState,
                .location = row.locName
            }
            Locations.Add(ld)
        Next
    End If
    ' 直接返回列表,WebMethod自动序列化为JSON数组
    Return Locations
End Function

Public Class LocationData
    Public Property id As Integer
    Public Property location As String
End Class

方案2:保留WebMethod返回字符串,前端手动解析JSON

在success回调里先把字符串解析为JSON数组:

success: function (result, status, xhr) {
    console.log(result.d);
    // 解析字符串为JSON数组
    var states = JSON.parse(result.d);
    $.each(states, function (key, value) {
        $("#ddlState").append($("<option></option>").val(value.id).html(value.location));
    });
}

另外,前端AJAX的data参数中,idLocation应传数值类型,建议修改为:

data: JSON.stringify({ idLocation: parseInt($(this).val()) })

保证参数类型与WebMethod的Integer匹配,避免潜在的参数解析问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:25:31