admin管理员组

文章数量:1278721

I am getting an exception:

> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.InvalidOperationException: TypeInfoResolver 'JsonBenchmark.DataSourceGenerationContext' did not provide property metadata for type 'JsonBenchmark.Data'.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForTypeProperties(IJsonTypeInfoResolver resolver, Type type)
   at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Deserialize(Utf8JsonReader& reader, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonTypeInfo`1 jsonTypeInfo)
   at JsonBenchmark.Benchmark.SystemTextJsonDeserializeSourceGenerator() in C:\Users\Ricardo.Peres\source\repos\JsonBenchmark\JsonBenchmark\Benchmark.cs:line 66
   at BenchmarkDotNet.Toolchains.InProcess.NoEmit.BenchmarkActionFactory.BenchmarkActionVoid.WorkloadActionUnroll(Int64 repeatCount)
   at BenchmarkDotNet.Engines.Engine.Measure(Action`1 action, Int64 invokeCount)
   at BenchmarkDotNet.Engines.Engine.RunIteration(IterationData data)
   at BenchmarkDotNet.Engines.EngineFactory.Jit(Engine engine, Int32 jitIndex, Int32 invokeCount, Int32 unrollFactor)
   at BenchmarkDotNet.Engines.EngineFactory.CreateReadyToRun(EngineParameters engineParameters)
   at BenchmarkDotNet.Toolchains.InProcess.NoEmit.InProcessNoEmitRunner.Runnable.RunCore(IHost host, BenchmarkCase benchmarkCase)
   at InvokeStub_Runnable.RunCore(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at BenchmarkDotNet.Toolchains.InProcess.NoEmit.InProcessNoEmitRunner.Run(IHost host, BenchmarkCase benchmarkCase)
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at BenchmarkDotNet.Toolchains.Results.ExecuteResult.LogIssues(ILogger logger, BuildResult buildResult)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.RunExecute(ILogger logger, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, IToolchain toolchain, BuildResult buildResult, IResolver resolver, IDiagnoser diagnoser, Int32 launchIndex)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.Execute(ILogger logger, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, IToolchain toolchain, BuildResult buildResult, IResolver resolver)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.RunCore(BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, ILogger logger, IResolver resolver, BuildResult buildResult)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.Run(BenchmarkRunInfo benchmarkRunInfo, Dictionary`2 buildResults, IResolver resolver, ILogger logger, EventProcessor eventProcessor, List`1 artifactsToCleanup, String resultsFolderPath, String logFilePath, Int32 totalBenchmarkCount, StartedClock& runsChronometer, Int32& benchmarksToRunCount, TaskbarProgress taskbarProgress)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.Run(BenchmarkRunInfo[] benchmarkRunInfos)
   at BenchmarkDotNet.Running.BenchmarkSwitcher.RunWithDirtyAssemblyResolveHelper(String[] args, IConfig config, Boolean askUserForInput)
   at BenchmarkDotNet.Running.BenchmarkSwitcher.Run(String[] args, IConfig config)
   at JsonBenchmark.Program.Main(String[] args) in C:\Users\Ricardo.Peres\source\repos\JsonBenchmark\JsonBenchmark\Program.cs:line 7

The exception is: "System.InvalidOperationException: TypeInfoResolver 'JsonBenchmark.DataSourceGenerationContext' did not provide property metadata for type 'JsonBenchmark.Data'."

When I try to serialize/deserialize a simple class:

public class Data
{
    public int Id { get; set; }
    public required string Name { get; set; }
    public DateTime Timestamp { get; set; }
}

Using a source generator (System.Text.Json):

[JsonSerializable(typeof(Data), GenerationMode = JsonSourceGenerationMode.Serialization)]
internal partial class DataSourceGenerationContext : JsonSerializerContext { }

The code itself runs when not running as a benchmark:

var data = new Data { Id = 1, Name = ".NET Serialization Benchmark", Timestamp = DateTime.Now };
var json = "{\"Id\":1,\"Name\":\"Ricardo\",\"Timestamp\":\"2025-02-17T13:45:53.2140627+00:00\"}";
System.Text.Json.JsonSerializer.Serialize(data);
System.Text.Json.JsonSerializer.Deserialize<Data>(json);
System.Text.Json.JsonSerializer.Serialize(data, DataSourceGenerationContext.Default.Data);
System.Text.Json.JsonSerializer.Deserialize(json, DataSourceGenerationContext.Default.Data);

But fails when I run it as part of a benchmark using BenchmarkDotNet:

public static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);

The failing code is either of: JsonSerializer.Serialize(data); JsonSerializer.Serialize(data, typeof(Data), DataSourceGenerationContext.Default);

According to all documentation I read, this should work, and, in fact, it does, just not as a benchmark. I am using .NET 9.

If I have, on my project (.csproj) file this:

<PropertyGroup>  
    <JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup>

Buf it I take it out, the result is the same. The code that fails is:

JsonSerializer.Deserialize(json, DataSourceGenerationContext.Default.Data);

It says that the DataSourceGenerationContext class does not provide metadata for type Data, which seems weird, because it should be generated by the source generator.

If, however, I set the GenerationMode property to JsonSourceGenerationMode.Metadata, on the JsonSerializableAttribute it works. But I wanted to use JsonSourceGenerationMode.Serialization because of the performance increase.

I am getting an exception:

> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.InvalidOperationException: TypeInfoResolver 'JsonBenchmark.DataSourceGenerationContext' did not provide property metadata for type 'JsonBenchmark.Data'.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForTypeProperties(IJsonTypeInfoResolver resolver, Type type)
   at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Deserialize(Utf8JsonReader& reader, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonTypeInfo`1 jsonTypeInfo)
   at JsonBenchmark.Benchmark.SystemTextJsonDeserializeSourceGenerator() in C:\Users\Ricardo.Peres\source\repos\JsonBenchmark\JsonBenchmark\Benchmark.cs:line 66
   at BenchmarkDotNet.Toolchains.InProcess.NoEmit.BenchmarkActionFactory.BenchmarkActionVoid.WorkloadActionUnroll(Int64 repeatCount)
   at BenchmarkDotNet.Engines.Engine.Measure(Action`1 action, Int64 invokeCount)
   at BenchmarkDotNet.Engines.Engine.RunIteration(IterationData data)
   at BenchmarkDotNet.Engines.EngineFactory.Jit(Engine engine, Int32 jitIndex, Int32 invokeCount, Int32 unrollFactor)
   at BenchmarkDotNet.Engines.EngineFactory.CreateReadyToRun(EngineParameters engineParameters)
   at BenchmarkDotNet.Toolchains.InProcess.NoEmit.InProcessNoEmitRunner.Runnable.RunCore(IHost host, BenchmarkCase benchmarkCase)
   at InvokeStub_Runnable.RunCore(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at BenchmarkDotNet.Toolchains.InProcess.NoEmit.InProcessNoEmitRunner.Run(IHost host, BenchmarkCase benchmarkCase)
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at BenchmarkDotNet.Toolchains.Results.ExecuteResult.LogIssues(ILogger logger, BuildResult buildResult)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.RunExecute(ILogger logger, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, IToolchain toolchain, BuildResult buildResult, IResolver resolver, IDiagnoser diagnoser, Int32 launchIndex)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.Execute(ILogger logger, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, IToolchain toolchain, BuildResult buildResult, IResolver resolver)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.RunCore(BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, ILogger logger, IResolver resolver, BuildResult buildResult)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.Run(BenchmarkRunInfo benchmarkRunInfo, Dictionary`2 buildResults, IResolver resolver, ILogger logger, EventProcessor eventProcessor, List`1 artifactsToCleanup, String resultsFolderPath, String logFilePath, Int32 totalBenchmarkCount, StartedClock& runsChronometer, Int32& benchmarksToRunCount, TaskbarProgress taskbarProgress)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.Run(BenchmarkRunInfo[] benchmarkRunInfos)
   at BenchmarkDotNet.Running.BenchmarkSwitcher.RunWithDirtyAssemblyResolveHelper(String[] args, IConfig config, Boolean askUserForInput)
   at BenchmarkDotNet.Running.BenchmarkSwitcher.Run(String[] args, IConfig config)
   at JsonBenchmark.Program.Main(String[] args) in C:\Users\Ricardo.Peres\source\repos\JsonBenchmark\JsonBenchmark\Program.cs:line 7

The exception is: "System.InvalidOperationException: TypeInfoResolver 'JsonBenchmark.DataSourceGenerationContext' did not provide property metadata for type 'JsonBenchmark.Data'."

When I try to serialize/deserialize a simple class:

public class Data
{
    public int Id { get; set; }
    public required string Name { get; set; }
    public DateTime Timestamp { get; set; }
}

Using a source generator (System.Text.Json):

[JsonSerializable(typeof(Data), GenerationMode = JsonSourceGenerationMode.Serialization)]
internal partial class DataSourceGenerationContext : JsonSerializerContext { }

The code itself runs when not running as a benchmark:

var data = new Data { Id = 1, Name = ".NET Serialization Benchmark", Timestamp = DateTime.Now };
var json = "{\"Id\":1,\"Name\":\"Ricardo\",\"Timestamp\":\"2025-02-17T13:45:53.2140627+00:00\"}";
System.Text.Json.JsonSerializer.Serialize(data);
System.Text.Json.JsonSerializer.Deserialize<Data>(json);
System.Text.Json.JsonSerializer.Serialize(data, DataSourceGenerationContext.Default.Data);
System.Text.Json.JsonSerializer.Deserialize(json, DataSourceGenerationContext.Default.Data);

But fails when I run it as part of a benchmark using BenchmarkDotNet:

public static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);

The failing code is either of: JsonSerializer.Serialize(data); JsonSerializer.Serialize(data, typeof(Data), DataSourceGenerationContext.Default);

According to all documentation I read, this should work, and, in fact, it does, just not as a benchmark. I am using .NET 9.

If I have, on my project (.csproj) file this:

<PropertyGroup>  
    <JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup>

Buf it I take it out, the result is the same. The code that fails is:

JsonSerializer.Deserialize(json, DataSourceGenerationContext.Default.Data);

It says that the DataSourceGenerationContext class does not provide metadata for type Data, which seems weird, because it should be generated by the source generator.

If, however, I set the GenerationMode property to JsonSourceGenerationMode.Metadata, on the JsonSerializableAttribute it works. But I wanted to use JsonSourceGenerationMode.Serialization because of the performance increase.

Share Improve this question edited Feb 24 at 15:29 Ricardo Peres asked Feb 24 at 12:06 Ricardo PeresRicardo Peres 14.6k5 gold badges62 silver badges77 bronze badges 4
  • 1 When you do System.Text.Json.JsonSerializer.Serialize(data); you are in fact serializing using reflection-based serialization. What does your csproj file look like? Do you have <JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault> set somewhere? What is the value of JsonSerializer.IsReflectionEnabledByDefault? – dbc Commented Feb 24 at 14:37
  • Are you building using NativeAOT? Can you share your full .csproj? – dbc Commented Feb 24 at 15:05
  • No, I am not. The csproj has nothing relevant, besides JsonSerializerIsReflectionEnabledByDefault (which I can take out), it's just refereces to two libraries: Newtonsoft.Json and BenchmarkDotNet – Ricardo Peres Commented Feb 24 at 15:09
  • github/dotnet/runtime/issues/78602 – Ricardo Peres Commented Feb 24 at 15:42
Add a comment  | 

1 Answer 1

Reset to default 1

I think I found out: as per this ticket, deserialization using JsonSourceGenerationMode.Serialization is not yet implemented! The alternative is to stick with the default.

本文标签: