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

迁移至System.Text.Json后,如何批量配置源生成序列化兼容AOT?

解决System.Text.Json源生成序列化批量配置问题

方案1:利用程序集级别的JsonSerializable特性(.NET 7+)

从.NET 7开始,JsonSerializable支持直接标记在程序集上,一次性指定整个命名空间或程序集内的所有类型,不用逐个手动添加特性。

比如要包含某个命名空间下的所有类型:

[assembly: JsonSerializable(typeof(MyLibrary.Models.*))]

如果要包含整个程序集的类型:

[assembly: JsonSerializable(Assembly = typeof(MyLibrary.SomeType).Assembly)]

还可以结合规则筛选,比如只包含特定基类的子类:

[assembly: JsonSerializable(typeof(MyBaseType), TypeInfoResolver = typeof(PolymorphicTypeResolver))]

注意:这个特性会自动纳入指定范围内的所有可序列化类型,无需逐个声明。

方案2:用MSBuild任务自动生成上下文类

可以写一个自定义MSBuild任务,在编译前扫描项目中的目标类型,自动生成带有所有JsonSerializable特性的MyLibraryContext类文件。

示例MSBuild任务代码:

public class GenerateJsonContextTask : Task
{
    [Required]
    public string OutputPath { get; set; }

    [Required]
    public string AssemblyPath { get; set; }

    public override bool Execute()
    {
        var assembly = Assembly.LoadFrom(AssemblyPath);
        // 筛选需要序列化的类型,这里以指定命名空间、排除抽象类和泛型定义为例
        var targetTypes = assembly.GetTypes()
            .Where(t => t.Namespace.StartsWith("MyLibrary.Models") && !t.IsAbstract && !t.IsGenericTypeDefinition);

        var codeBuilder = new StringBuilder();
        codeBuilder.AppendLine("using System.Text.Json.Serialization;");
        codeBuilder.AppendLine();
        codeBuilder.AppendLine("internal partial class MyLibraryContext : JsonSerializerContext");
        codeBuilder.AppendLine("{");
        foreach (var type in targetTypes)
        {
            codeBuilder.AppendLine($"    [JsonSerializable(typeof({type.FullName}))]");
        }
        codeBuilder.AppendLine("}");

        File.WriteAllText(OutputPath, codeBuilder.ToString());
        return true;
    }
}

在项目文件中引用这个任务,配置它在编译前执行,就能自动生成上下文类文件。

方案3:自定义源代码生成器

编写一个.NET源代码生成器,在编译时扫描项目中的语法树或程序集,自动生成JsonSerializationContext的部分类,批量添加JsonSerializable特性。

核心实现步骤:

  1. 创建类库项目,引用Microsoft.CodeAnalysis.CSharp和Microsoft.CodeAnalysis.Analyzers。
  2. 实现ISourceGenerator接口,在Execute方法中扫描符合条件的类型。
  3. 生成包含所有JsonSerializable特性的代码,并注入到编译过程中。

示例生成器核心代码片段:

[Generator]
public class JsonContextGenerator : ISourceGenerator
{
    public void Initialize(GeneratorInitializationContext context)
    {
        // 初始化逻辑,比如注册语法接收器
    }

    public void Execute(GeneratorExecutionContext context)
    {
        // 筛选目标类型,这里以类名以Model结尾为例
        var targetTypes = context.Compilation.SyntaxTrees
            .SelectMany(tree => tree.GetRoot().DescendantNodes())
            .OfType<ClassDeclarationSyntax>()
            .Where(c => c.Identifier.Text.EndsWith("Model"))
            .Select(c => context.Compilation.GetSemanticModel(c.SyntaxTree).GetDeclaredSymbol(c))
            .OfType<INamedTypeSymbol>();

        var code = new StringBuilder();
        code.AppendLine("using System.Text.Json.Serialization;");
        code.AppendLine("internal partial class MyLibraryContext : JsonSerializerContext {");
        foreach (var type in targetTypes)
        {
            code.AppendLine($"    [JsonSerializable(typeof({type.ToDisplayString()}))]");
        }
        code.AppendLine("}");

        context.AddSource("MyLibraryContext.g.cs", code.ToString());
    }
}

把这个生成器打包成NuGet包,引用到类库项目中,编译时就会自动生成对应的上下文类。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 01:15:17