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

C#使用System.Text.Json有条件序列化Link对象为字符串的问题咨询

你遇到的报错核心原因是项目使用了 System.Text.Json 的源生成序列化模式,自定义 Converter 中调用默认序列化时,临时构造的配置没有绑定预先生成的序列化元数据,因此无法找到 Link 类型的映射信息。

排查步骤

  • 首先确认序列化配置:检查项目中是否定义了继承自 JsonSerializerContext 的分部类,且序列化/反序列化方法传入了该上下文实例,而非使用默认的反射序列化模式。
  • 检查自定义 Converter 逻辑:如果是参考通用方案新建了移除当前 Converter 的 JsonSerializerOptions 实例,该实例未关联你的源生成上下文,就会抛出找不到元数据的错误。
  • 验证 JsonSerializable 特性的标注位置:源生成的 JsonSerializable 特性必须标注在自定义的 JsonSerializerContext 分部类上才会生效,直接标注在 Link 实体类上无效。

解决方案

方案1:调整 Converter 默认序列化逻辑(推荐)

修改自定义 LinkConverter 的读写逻辑,避免重复构造无元数据的配置:

public class LinkConverter : JsonConverter<Link>
{
    // 自定义判断条件:满足则序列化为URL字符串,可替换为你的业务规则
    private static bool ShouldCollapseToUrl(Link link)
    {
        return string.IsNullOrEmpty(link.Rel) 
            && (link.Rels == null || !link.Rels.Any())
            // 补充其他属性为空的判断逻辑
            && !string.IsNullOrEmpty(link.Href);
    }

    public override void Write(Utf8JsonWriter writer, Link value, JsonSerializerOptions options)
    {
        if (ShouldCollapseToUrl(value))
        {
            writer.WriteStringValue(value.Href);
            return;
        }
        // 构造排除当前Converter的新配置,避免循环调用
        var newOptions = new JsonSerializerOptions(options);
        var currentConverter = newOptions.Converters.OfType<LinkConverter>().FirstOrDefault();
        if (currentConverter != null)
        {
            newOptions.Converters.Remove(currentConverter);
        }
        // 绑定源生成上下文的TypeInfoResolver
        newOptions.TypeInfoResolver = ActivityPubJsonContext.Default;
        JsonSerializer.Serialize(writer, value, newOptions);
    }

    public override Link Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 支持字符串格式的反序列化
        if (reader.TokenType == JsonTokenType.String)
        {
            return new Link(reader.GetString());
        }
        // 对象格式走默认反序列化
        var newOptions = new JsonSerializerOptions(options);
        var currentConverter = newOptions.Converters.OfType<LinkConverter>().FirstOrDefault();
        if (currentConverter != null)
        {
            newOptions.Converters.Remove(currentConverter);
        }
        newOptions.TypeInfoResolver = ActivityPubJsonContext.Default;
        return JsonSerializer.Deserialize<Link>(ref reader, newOptions)!;
    }
}

注意把代码中的 ActivityPubJsonContext 替换为你项目中实际定义的 JsonSerializerContext 子类名。

方案2:切换为反射序列化模式(临时验证用)

如果不需要源生成的性能优化,可以直接修改序列化配置,关闭源生成模式,使用反射序列化,即可兼容通用的自定义Converter逻辑:

var options = new JsonSerializerOptions
{
    // 其他原有配置
    TypeInfoResolver = null, // 不使用源生成的TypeInfo
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:36:02