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

ASP.NET中从外部API筛选国家法定假日数据及JArray索引异常排查

解决异常并实现国家法定假日筛选功能

首先,咱们先拆解你遇到的问题:

异常原因分析

你看到的ArgumentException是因为API返回的是JSON数组(用[]包裹),反序列化后的content是JArray类型,但你试图用访问JObject属性的方式(content["HolidayCaption"])去读取它,这完全不符合JArray的访问规则——JArray只能通过索引(比如content[0])或者遍历元素来访问内容。另外,代码里的SelectTokens("aa")是无意义的,API返回的结构里根本没有aa这个路径,这也会导致你拿不到任何数据。

分步解决方案

1. 修正数据解析逻辑,加入筛选条件

我们需要遍历返回的JSON数组,筛选出is_national_holiday == true的记录,同时修正模型的使用逻辑:

修正后的Repository代码

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

public async Task<HoliDate> GetHolidaysAsync()
{
    var client = new RestClient("https://api-harilibur.vercel.app/api");
    var request = new RestRequest(Method.GET);
    
    // 注意:原代码里的APIKey头是"Application/Json",这看起来不太对,如果API需要合法的Key请替换成正确值
    // client.AddHeader("APIKey", "YourValidAPIKeyHere");

    var response = await client.ExecuteAsync(request);
    
    if (response.IsSuccessful && !string.IsNullOrEmpty(response.Content))
    {
        // 因为返回的是数组,直接反序列化为JArray
        var holidayArray = JArray.Parse(response.Content);
        
        // 筛选国家法定假日,同时映射到Holiday模型
        var nationalHolidays = holidayArray
            .Cast<JObject>()
            .Where(holiday => holiday["is_national_holiday"]?.Value<bool>() == true)
            .Select(holiday => new Holiday
            {
                holiday_date = holiday["holiday_date"]?.Value<DateTime>() ?? DateTime.MinValue,
                holiday_name = holiday["holiday_name"]?.Value<string>() ?? string.Empty,
                is_national_holiday = true // 已经筛选过,直接设为true即可
            })
            .ToList();

        // 返回包装后的模型,如果不需要HolidayCaption可以考虑移除该字段
        return new HoliDate
        {
            // 如果需要HolidayCaption,可以设置为第一个假日的日期,或者年度(比如DateTime.Now.Year)
            HolidayCaption = nationalHolidays.FirstOrDefault()?.holiday_date ?? DateTime.MinValue,
            Holiday = nationalHolidays
        };
    }

    // 打印错误信息便于调试
    System.Console.WriteLine($"请求失败或无内容:{response.Content}");
    return null;
}

2. 修正模型(可选优化)

原模型里的HolidayCaption字段在API返回中不存在,如果你不需要这个字段,可以直接简化模型,或者明确它的用途(比如表示年度):

public class HoliDate
{
    // 如果不需要可以删除这个字段
    public DateTime HolidayCaption { get; set; }
    public IEnumerable<Holiday> Holiday { get; set; }
}

public class Holiday
{
    public DateTime holiday_date { get; set; }
    public string holiday_name { get; set; }
    public bool is_national_holiday { get; set; }
}

3. Controller代码保持不变(可加空列表判断)

如果筛选后没有国家法定假日,nationalHolidays会是空列表,你可以在Controller里补充判断:

[Route("Holiday")]
[HttpGet]
public async Task<IActionResult> GetByIdAsync()
{
    var model = await repository.GetHolidaysAsync();
    
    if (model == null) 
        return NotFound("获取假日数据失败");
    
    if (!model.Holiday.Any())
        return Ok(new { Message = "当前没有国家法定假日记录" });
    
    return Ok(model);
}

额外优化建议

  • 不要重复创建HttpClient/RestClient:每次请求都新建客户端会消耗不必要的资源,建议将RestClient注册为单例(在ASP.NET Core中可以用services.AddSingleton<RestClient>())。
  • 异常处理增强:可以捕获反序列化过程中的异常,比如JsonException,避免程序崩溃。
  • API头修正:原代码里的http.DefaultRequestHeaders.Add("APIKey", "Application/Json")看起来很奇怪,Application/Json是Content-Type的常用值,不是APIKey,如果该API需要认证,请替换为正确的API密钥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:17:40