-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
This issue has been moved from a ticket on Developer Community.
Hi,
I'm trying to switch from Newtonsoft to System.Text.Json with source generation.
I'm experiencing an issue with serialization of records in another assembly.
I created a simple project, I have a library with a single file containing the record (I don't use terse syntax to easily switch to and from class type)
using System;
using System.Runtime.CompilerServices;
namespace ClassLibrary1
{
public record Person
{
public Person(string name) => Name = name;
public string Name { get; }
}
}and an executable with the following code, using System.Text.Json source generation:
using System.Text.Json;
using System.Text.Json.Serialization;
using ClassLibrary1;
using static System.Console;
var context = new Context();
var value = new Person("class");
var serialized = JsonSerializer.Serialize(value, typeof(Person), context);
WriteLine(serialized);
var unserialized = (Person) JsonSerializer.Deserialize(serialized, typeof(Person), context);
[JsonSerializable(typeof(Person))]
partial class Context : JsonSerializerContext
{
}The output of the WriteLine is
{}
and then deserialization fails with the following error as it does not find the name:
Unhandled exception. System.InvalidOperationException: Each parameter in the deserialization constructor on type 'ClassLibrary1.Person' must bind to an object property or field on deserialization. Each parameter name must match with a property or field on the object. The match can be case-insensitive
Switching the type of Person from record to class fixes the issue. Also having the record directly in the executable (in the same assembly where the source is generated) fixes the issue.
I tried to reproduce by the generated code of the record (IEquatable, ToString, ...) manually in the class, but I can't reproduce the record issue.
By the way, if I look at the generated code in my Visual Studio
If I have a look at the Person.g.cs
For serialization it seems to contains the right code:
private static void PersonSerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, global::ClassLibrary1.Person? value)
{
if (value == null)
{
writer.WriteNullValue();
return;
}
writer.WriteStartObject();
writer.WriteString(PropName_Name, value.Name);
writer.WriteEndObject();
}But if I look at the disassembly of my executable (I'm using dotPeek), I see why my serialized object is empty
private static void PersonSerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, global::ClassLibrary1.Person? value)
{
if (value == null)
{
writer.WriteNullValue();
return;
}
writer.WriteStartObject();
writer.WriteEndObject();
}I attached the project, it's fairly simple.
Thank you
Original Comments
(no comments)
Original Solutions
(no solutions)
