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

ASP.NET Core中HttpClient调用API后,jQuery Ajax无法按ID取数的问题

ASP.NET Core接口调用问题:前端Ajax无法获取外部API返回数据

我在ASP.NET Core项目中碰到个问题:控制器里用HttpClient调用外部API,但前端通过jQuery Ajax按ID请求/GetCivilID接口时,拿不到正确的数据。

控制器代码

[HttpGet("/GetCivilID")]
public async Task<IActionResult> getId(Users usr)
{
    var randid = GeneratePassword1();

    var randomNumberUrl = _config["API:Url"];
    var basic = Convert.ToBase64String(Encoding.UTF8.GetBytes(_config["API:UserName"] + ":" + _config["DemographyAPI:Password"]));
    var ClientName = _config["D:ClientName"];
    var ClientKey = _config["D:ClientKey"];
    var payLoad = new Dictionary<string, string>();
    payLoad.Add("CivilID", usr.CivilId);
    payLoad.Add("ReferenceID", randid); //"20221129092059133"

    var jsonObject = JsonConvert.SerializeObject(payLoad);
    var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Authorization", $"Basic {basic}");
        client.DefaultRequestHeaders.Add("Accept", "*/*");
        client.DefaultRequestHeaders.Add("ClientName", ClientName);
        client.DefaultRequestHeaders.Add("ClientKey", ClientKey);

        var response = await client.PostAsync(randomNumberUrl, content);

        response.EnsureSuccessStatusCode();

        var res = await response.Content.ReadAsStringAsync();

        if (response.IsSuccessStatusCode)
        {
            // var dict = JObject.Parse(res.ToString()).SelectToken("Response").ToObject<Dictionary<string,object>>();
            //var dictionary = JsonConvert.DeserializeObject<Dictionary<string, UsersBM>>(res)

            var dictionary = JsonConvert.DeserializeObject(res);

            return Json(dictionary);
        } 
   }
}

前端jQuery代码

$("#Ids").keydown(function (e) {
    if (e.which == 13) {
        alert("enter");

        $.ajax({
            url: "/GetCivilID",
            type: "GET",
            data: { CivilId : $("#CivilIds").val()},
            dataType: "json",
            processData: true,
            success: function (data, status) {
                debugger;
                //console.log(dataResponse.Header.Payload.ResponseMessage.Details.LATIN_NAME1);
                console.log("data :" + data);
                alert(data);
                //data = Full.Response.Header.Payload.ResponseMessage.Details.LATIN_NAME1);
                //alert(data);
            }
        });
    }
});

外部API返回的JSON结构

"Payload": {
    "ResponseCode": "200",
    "ResponseText": "SUCCESS",
    "ResponseFlag": "True",
    "ResponseMessage": {
        "id": "28407010728154",
        "Text": "Success",
        "Details": {
            "Id_NO": "284070105551",
            "LATIN_NAME1": "ALLIJAHAN",
            "LATIN_NAME2": "VEMPALLI",
            "LATIN_NAME3": "VEMPALLI",
            "LATIN_NAME4": "SAB"
        }
    }
}

排查与修复方案

1. 请求方法与参数绑定不匹配

控制器标了[HttpGet],但用Users usr接收参数——GET请求默认没法直接绑定复杂对象,前端传的CivilId参数可能没正确映射到usr.CivilId。

修复方式二选一:

  • 改成单个参数接收:public async Task<IActionResult> getId(string civilId),前端保持data: { civilId : $("#CivilIds").val()}(注意参数名大小写一致)。
  • 把控制器改成[HttpPost],前端Ajax的type设为POST,并添加contentType: "application/json",用JSON.stringify传递参数:
    data: JSON.stringify({ CivilId : $("#CivilIds").val()}),
    contentType: "application/json",
    

2. 配置项键名可能错误

控制器里_config["DemographyAPI:Password"]、_config["D:ClientName"]这些键名,检查appsettings.json里的配置是不是完全对应,要是配置项不存在,会导致Basic Auth头或者ClientName/ClientKey为空,外部API直接拒绝请求。

3. 未处理外部API异常

response.EnsureSuccessStatusCode()会在外部API返回非2xx状态码时抛出异常,控制器没加try-catch,直接返回500错误,前端收不到有效响应。

添加异常捕获:

try
{
    var response = await client.PostAsync(randomNumberUrl, content);
    response.EnsureSuccessStatusCode();
    var res = await response.Content.ReadAsStringAsync();
    // 反序列化逻辑
}
catch (HttpRequestException ex)
{
    return StatusCode(StatusCodes.Status500InternalServerError, new 
    { 
        Message = "调用外部身份验证API失败", 
        Error = ex.Message 
    });
}

4. JSON反序列化不规范

现在用JsonConvert.DeserializeObject(res)返回的是object类型,前端没法直接访问嵌套属性。建议创建对应实体类来反序列化,简化数据处理:

创建实体类:

public class ApiResponse
{
    public Payload Payload { get; set; }
}

public class Payload
{
    public string ResponseCode { get; set; }
    public string ResponseText { get; set; }
    public ResponseMessage ResponseMessage { get; set; }
}

public class ResponseMessage
{
    public Details Details { get; set; }
}

public class Details
{
    public string Id_NO { get; set; }
    public string LATIN_NAME1 { get; set; }
    public string LATIN_NAME2 { get; set; }
    // 其他需要的属性
}

修改反序列化代码:

var apiResponse = JsonConvert.DeserializeObject<ApiResponse>(res);
return Json(apiResponse.Payload.ResponseMessage.Details); // 直接返回需要的详情数据,减少前端层级

5. 前端响应处理错误

前端console.log("data :" + data)会把JSON对象转成[object Object]字符串,没法查看具体内容,改成console.log("data :", data)才能展开看结构。如果控制器返回完整的外部API响应,前端要按正确层级访问属性:data.Payload.ResponseMessage.Details.LATIN_NAME1。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 12:35:28