fix(json): 修复有关 JSON 的一系列问题#2931
Merged
Merged
Conversation
…ers and null safety - Replace GetValue<T>() with ToObject<T>() via CompatOptions to handle type mismatches - Add FlexibleBoolConverter and FlexibleStringConverter for resilient parsing - Add null-conditional (? / ?.) propagation to server name and JSON field access - Centralize ParseJson() helper to ensure consistent options everywhere - Replace raw string JSON construction with JsonObject for LabyMod libraries
…, forge list, and modpack parsing - Add robust _GetDateTime() to handle both DateTime and string JSON values in McVersionClassifier - Replace unsafe GetValue<T>() with TryGetValue<T>() in _GetString() - Use FetchString instead of FetchJson for Forge HTML version list page - Replace GetValue<T>() with ToObject<T>() for modpack file fields
…unified API - Add JsonCompat class in PCL.Core.Utils with centralized SerializerOptions, NodeOptions, DocumentOptions, converters, and helper methods (ParseNode, ToObject, FromObject, Merge) - Replace all JsonNodeExtensions.* references (app project) with JsonCompat.* (core library) site-wide - Make ToObject<T>() an extension method on JsonNode for cleaner call syntax - Optimize ExpandoObjectConverter with direct element-kind conversion instead of re-serializing - Fix YggdrasilCredential record semantics (init-only properties, property initializers) - Improve SignOutAsync to check NoContent status before parsing response body - Use primary constructor syntax for JsonWebToken
Reviewer's Guide引入集中管理的 JsonCompat 实用工具,使用更宽松的 System.Text.Json 默认配置,并迁移代码库统一使用它。同时收紧各处 JSON 使用方式、空值处理路径以及部分协议/记录定义,以避免反序列化和运行时错误。 更新后的 YggdrasilLegacyClient.SignOutAsync 流程时序图sequenceDiagram
participant Client as YggdrasilLegacyClient
participant HttpReq as HttpRequest
participant Server as YggdrasilServer
participant JsonC as JsonCompat
Client->>HttpReq: CreatePost(address)
Client->>HttpReq: WithHeaders(options.Headers)
Client->>HttpReq: WithJsonContent(signoutData)
Client->>HttpReq: SendAsync(options.GetClient.Invoke(), token)
HttpReq-->>Client: HttpResponseMessage response
alt StatusCode == HttpStatusCode.NoContent
Client-->>Client: return (true, null)
else StatusCode != HttpStatusCode.NoContent
Client->>HttpReq: AsStringAsync(token)
HttpReq-->>Client: content
Client->>JsonC: ParseNode(content)
JsonC-->>Client: JsonNode data
Client-->>Client: errorMessage = data["errorMessage"]?.ToString()
Client-->>Client: return (false, errorMessage)
end
文件级变更
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 以:
Getting Help
Original review guide in EnglishReviewer's GuideIntroduce a centralized JsonCompat utility with relaxed System.Text.Json defaults and migrate the codebase to use it, while tightening up various JSON usages, null-handling paths, and a few protocol/record definitions to avoid deserialization and runtime errors. Sequence diagram for updated YggdrasilLegacyClient.SignOutAsync flowsequenceDiagram
participant Client as YggdrasilLegacyClient
participant HttpReq as HttpRequest
participant Server as YggdrasilServer
participant JsonC as JsonCompat
Client->>HttpReq: CreatePost(address)
Client->>HttpReq: WithHeaders(options.Headers)
Client->>HttpReq: WithJsonContent(signoutData)
Client->>HttpReq: SendAsync(options.GetClient.Invoke(), token)
HttpReq-->>Client: HttpResponseMessage response
alt StatusCode == HttpStatusCode.NoContent
Client-->>Client: return (true, null)
else StatusCode != HttpStatusCode.NoContent
Client->>HttpReq: AsStringAsync(token)
HttpReq-->>Client: content
Client->>JsonC: ParseNode(content)
JsonC-->>Client: JsonNode data
Client-->>Client: errorMessage = data["errorMessage"]?.ToString()
Client-->>Client: return (false, errorMessage)
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
… freeze SerializerOptions - Add TryGetDateTime() and TryParseDateTime() to JsonCompat, shared with FlexibleDateTimeConverter - Simplify McVersionClassifier._GetDateTime() by delegating to JsonCompat.TryGetDateTime() - Freeze SerializerOptions with MakeReadOnly() to prevent accidental mutation - Wrap SignOutAsync parsing in try/catch to handle non-JSON responses gracefully
Big-Cake-jpg
approved these changes
May 30, 2026
Member
Big-Cake-jpg
left a comment
There was a problem hiding this comment.
简单测了下似乎没啥问题,先就这样吧,爆了问题再修……(
LuLu-ling
approved these changes
May 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
新增
PCL.Core/Utils/JsonCompat作为统一的 JSON 兼容解析入口,替代原先散落在Plain Craft Launcher 2项目中的JsonNodeExtensions,并全部替换调用方式。JsonCompat— 集中管理SerializerOptions/NodeOptions/DocumentOptions,内置FlexibleDateTimeConverter、FlexibleBoolConverter、FlexibleStringConverter三个宽松转换器,提供ParseNode()、ToObject<T>()(扩展方法)、FromObject<T>()、Merge()等辅助方法JsonNode.Parse()、GetValue<T>()、JsonSerializer.*裸调用全部替换为JsonCompat的对应 API,确保所有 JSON 解析使用一致的宽松选项,消除因格式/类型不匹配导致的反序列化崩溃?.空条件传播FetchJson改为FetchString(返回内容实为 HTML)ExpandoObjectConverter优化 — 用直接值类型判断替代二次序列化SignOutAsync优化 — 204 NoContent 时提前返回,避免解析空响应set改为initSummary by Sourcery
引入集中化的 JSON 兼容性工具,并迁移现有的 JSON 解析/序列化逻辑以使用该工具,从而在整个代码库中实现更健壮、更宽松的处理。
Bug 修复:
增强功能:
JsonCompat工具统一 JSON 序列化器、文档和节点选项(包括自定义转换器),以模拟类似 Newtonsoft.Json 的宽松行为。ExpandoObject的 JSON 转换。DateTime解析并容忍不同格式和时区,使版本和日期处理更加可靠。JsonNode解析/合并及分散的辅助函数,这些新工具支持深度合并和宽容的类型转换。Original summary in English
Summary by Sourcery
Introduce a centralized JSON compatibility utility and migrate existing JSON parsing/serialization to use it for more robust, lenient handling across the codebase.
Bug Fixes:
Enhancements: