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

RestSharp升级后无法反序列化JIRA API返回JSON的问题排查

问题:RestSharp升级后反序列化JIRA API返回数据失败

场景复现

通过RestSharp调用JIRA API获取用户组成员列表,旧版本RestSharp可正常运行,升级至最新版本后抛出反序列化错误。

调用代码

options.Authenticator = new HttpBasicAuthenticator(_jiraConfig.UserName, _jiraConfig.Token);
options.BaseUrl = new Uri(_jiraConfig.Url);
_restClient = new RestClient(options);
var request = new RestRequest($"rest/api/2/group/member?groupname={_jiraConfig.GroupName}&includeInactiveUsers=false&startAt={start}&maxResults=100", Method.Get);
PagedQueryResult<JiraGroupUser> jiraUsers = await _restClient.GetAsync<PagedQueryResult<JiraGroupUser>>(request);

JIRA API返回的JSON数据

{
    "self": "https://xxx.atlassian.net/rest/api/2/group/member?includeInactiveUsers=false&maxResults=50&groupId=f4a5587d-92ec-4cbf-824e-8489f38d147f&startAt=0",
    "nextPage": "https://xxx.atlassian.net/rest/api/2/group/member?includeInactiveUsers=false&maxResults=50&groupId=f4a5587d-92ec-4cbf-824e-8489f38d147f&startAt=50",
    "maxResults": 50,
    "startAt": 0,
    "total": 94,
    "isLast": false,
    "values": [
        {
            "self": "https://xxx.atlassian.net/rest/api/2/user?accountId=yyy",
            "accountId": "yyy",
            "avatarUrls": {
                "48x48": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/yyy/aaa/48",
                "24x24": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/yyy/aaa/24",
                "16x16": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/yyy/aaa/16",
                "32x32": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/yyy/aaa/32"
            },
            "displayName": "ABC",
            "active": true,
            "timeZone": "Europe/Zurich",
            "accountType": "atlassian"
        },
        {
            "self": "https://xxx.atlassian.net/rest/api/2/user?accountId=zzz",
            "accountId": "zzz",
            "avatarUrls": {
                "48x48": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/zzz/bbb/48",
                "24x24": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/zzz/bbb/24",
                "16x16": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/zzz/bbb/16",
                "32x32": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/zzz/bbb/32"
            },
            "displayName": "DEF",
            "active": true,
            "timeZone": "Europe/Zurich",
            "accountType": "app"
        }
    ]
}

反序列化模型类

internal class PagedQueryResult<T> : IEnumerable<T>
{
    public List<T> Values { get; set; } = new List<T>();
    public int StartAt { get; set; }
    public int MaxResults { get; set; }
    public int Total { get; set; }
    public bool IsLast { get; set; }
    public string Self { get; set; }
    public string NextPage { get; set; }

    public PagedQueryResult()
    {
    }

    public IEnumerator<T> GetEnumerator()
    {
        return Values.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return Values.GetEnumerator();
    }
}
public class JiraGroupUser
{
    public string AccountId { get; set; }
    public string AccountType { get; set; }
    public bool Active { get; set; }
    public string DisplayName { get; set; }
    public string EmailAddress { get; set; }
    public string TimeZone { get; set; }
    public string Self { get; set;}
}

错误信息

System.Text.Json.JsonException: 'The JSON value could not be converted to CloudToolsUsersExporter.JiraExporter.Models.PagedQueryResult`1[CloudToolsUsersExporter.JiraExporter.Models.JiraGroupUser]. Path: $ | LineNumber: 0 | BytePositionInLine: 1.'

问题原因

  1. 序列化器默认行为变更:RestSharp新版本默认使用System.Text.Json作为序列化器,而旧版本默认使用Newtonsoft.Json。两者核心差异在于:
    • System.Text.Json默认不忽略JSON中未在模型定义的字段,且默认区分属性名大小写;
    • Newtonsoft.Json默认忽略未知字段,且默认不区分大小写。
  2. 属性名匹配问题:JSON中的字段为驼峰命名(如maxResults、isLast),而模型类属性为Pascal命名(如MaxResults、IsLast),System.Text.Json默认大小写敏感,会导致字段映射失败。
  3. 未定义的avatarUrls字段触发了System.Text.Json的反序列化错误。

解决办法

方法1:配置System.Text.Json适配JIRA JSON格式

在创建RestClient时,配置JsonSerializerOptions,开启大小写不敏感匹配并忽略未知字段:

var options = new RestClientOptions(_jiraConfig.Url)
{
    Authenticator = new HttpBasicAuthenticator(_jiraConfig.UserName, _jiraConfig.Token),
    JsonSerializerOptions = new System.Text.Json.JsonSerializerOptions
    {
        PropertyNameCaseInsensitive = true, // 忽略属性名大小写
        IgnoreUnknownFields = true, // 忽略JSON中未定义的字段
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase // 自动映射驼峰与Pascal命名
    }
};
_restClient = new RestClient(options);

方法2:给模型添加特性适配

如果不需要全局配置,可以给模型类/属性添加特性:

  • 给JiraGroupUser添加[JsonExtensionData]捕获未知字段,避免报错:
    public class JiraGroupUser
    {
        public string AccountId { get; set; }
        public string AccountType { get; set; }
        public bool Active { get; set; }
        public string DisplayName { get; set; }
        public string EmailAddress { get; set; }
        public string TimeZone { get; set; }
        public string Self { get; set;}
        
        [JsonExtensionData]
        public Dictionary<string, JsonElement> ExtraFields { get; set; } // 存储avatarUrls等未知字段
    }
    
  • 给模型属性添加[JsonPropertyName]明确指定JSON字段名:
    internal class PagedQueryResult<T> : IEnumerable<T>
    {
        [JsonPropertyName("values")]
        public List<T> Values { get; set; } = new List<T>();
        [JsonPropertyName("startAt")]
        public int StartAt { get; set; }
        [JsonPropertyName("maxResults")]
        public int MaxResults { get; set; }
        // 其他属性同理
    }
    

方法3:切换回Newtonsoft.Json

如果希望保留旧版本的序列化行为,可以安装RestSharp.Serializers.NewtonsoftJson NuGet包,然后配置RestSharp使用Newtonsoft.Json:

var options = new RestClientOptions(_jiraConfig.Url)
{
    Authenticator = new HttpBasicAuthenticator(_jiraConfig.UserName, _jiraConfig.Token)
};
_restClient = new RestClient(options)
    .UseNewtonsoftJson(); // 切换为Newtonsoft.Json序列化器

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 16:42:06