ASP.NET Core中HttpClient调用API后,jQuery Ajax无法按ID取数的问题
我在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

