source generator 仅对 [jsonserializable] 显式标注且满足 partial、可见性、编译时可达的类型生成序列化代码;appjsoncontext.default.product 报 cs0260 通常因类未标记为 partial、非 public/internal、项目未引用 system.text.json 或目标框架过低,或 [jsonserializable] 类型在编译期不可解析所致。

Source Generator 不会自动为所有类型生成 JSON 序列化代码——它只响应你显式声明的 JsonSerializerContext 子类中用 [JsonSerializable] 标注的类型,且必须满足 partial、可见性、编译时可达三个硬性条件,否则静默跳过。
为什么 AppJsonContext.Default.Product 没有生成或报 CS0260
这是最常被忽略的“假失败”:生成器根本没触发,或生成了但编译器不认。关键原因不是代码写错,而是上下文未被 Roslyn 识别为有效源生成目标:
-
AppJsonContext必须是internal partial class或public partial class,不能是private或嵌套在其他类内 - 该类所在的项目必须引用
System.Text.Json(≥ .NET 6.0),且目标框架为net6.0或更高(net5.0仅部分支持,netstandard2.0不支持) -
[JsonSerializable]的参数类型(如typeof(Person))必须在编译时完全可解析:不能是dynamic、object、未闭合泛型(如List),也不能是仅存在于运行时的类型(如ExpandoObject) - 如果类型含
private字段并希望序列化,必须加[JsonInclude],且该属性需在同一个程序集中可见
如何确认源生成是否真正生效
别只看编译是否通过——要验证生成逻辑是否跑通,最直接的方式是检查编译输出目录中的 .g.cs 文件:
- 启用 MSBuild 详细日志(
dotnet build -v:d),搜索关键词System.Text.Json.SourceGeneration,确认有类似Generated source for type 'Person'的日志 - 构建后,在
obj/Debug/net8.0/(路径依目标框架而定)下查找*JsonContext*.g.cs文件,打开确认内容是否包含PersonSerializer、SerializePerson等方法 - 若文件存在但调用
AppJsonContext.Default.Person报 CS0260,大概率是命名空间不一致或AppJsonContext类未被标记为partial - 若文件完全不存在,说明
[JsonSerializable]未被扫描到——检查该类是否被条件编译(#if DEBUG)包裹,或是否在InternalsVisibleTo范围外
使用生成上下文时必须避开的调用陷阱
源生成启用后,旧式静态 API 会绕过生成代码,性能无提升:
- ❌ 错误用法:
JsonSerializer.Serialize<person>(p)</person>—— 这仍走反射路径,AppJsonContext形同虚设 - ✅ 正确用法:
JsonSerializer.Serialize(p, AppJsonContext.Default.Person),其中Person是上下文里自动生成的JsonTypeInfo<person></person>属性 - 序列化集合时不能直接传
List<person></person>,必须用AppJsonContext.Default.ListPerson(前提是你在上下文中写了[JsonSerializable(typeof(List<person>))]</person>) - 若需复用同一上下文处理多个类型,确保所有
[JsonSerializable]都在同一partial class中声明;跨多个上下文会导致重复生成和命名冲突
真正容易被卡住的点,往往不在怎么写 [JsonSerializable],而在于生成器是否被 Roslyn 加载、类型是否在编译期“看得见”、以及调用时有没有精准命中生成的 JsonTypeInfo 属性——这三个环节断掉任意一个,就等于没开源生成。











