-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serialization of ReadOnlyMemory<byte>
with [JsonIgnore]
attribute in .NET 6 and .NET 7 RC1
#76807
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsDescription
Reproduction StepsThe issue can be reproduced using the following two files
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<!-- Works with .NET 6 -->
<TargetFramework>net6.0</TargetFramework>
<!-- Fails with .NET 7 -->
<!--<TargetFramework>net7.0</TargetFramework>-->
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace JsonSerializeRepro;
public static class Program
{
public static void Main(string[] args)
{
ReadOnlyMemory<byte> binaryData = Array.Empty<byte>();
InstallScriptRequest installScriptRequest = new(binaryData, upgrade: true);
string json = JsonSerializer.Serialize(installScriptRequest);
Console.WriteLine(json);
}
}
public class InstallScriptRequest
{
/// <inheritdoc/>
[JsonIgnore]
public int BinaryDataMaxSize => 1024 * 1024;
/// <summary>ZIP archive that contains the script package to install.</summary>
[JsonIgnore]
public ReadOnlyMemory<byte> BinaryData { get; set; }
public bool Upgrade { get; }
public InstallScriptRequest(ReadOnlyMemory<byte> binaryData, bool upgrade)
{
this.BinaryData = binaryData;
this.Upgrade = upgrade;
}
} Expected behaviorWhen run as .NET 6 project, I get: Actual behaviorWhen run as .NET 7 project (RC1), I get:
Regression?Maybe it's a regression. I'm not sure. Known WorkaroundsNo response ConfigurationTested on Windows 11. However, I don't believe it's a platform-specific issue. Other informationNo response
|
ReadOnlyMemory<byte>
with [JsonIgnore]
attribute in .NET 6 and .NET 7ReadOnlyMemory<byte>
with [JsonIgnore]
attribute in .NET 6 and .NET 7 RC1
I can reproduce -- root cause is infrastructural changes related to #63686, namely we're now eagerly computing type metadata even for properties that have been marked Line 302 in d520f57
We should try to fix this in .NET 7 since it clearly breaks a common user workaround when dealing with unsupported property types. In the meantime, a simpler workaround for the issue would be to register a dummy converter for ReadOnlyMemory: var options = new JsonSerializerOptions { Converters = { new ReadOnlyMemoryConverter() } };
JsonSerializer.Serialize(installScriptRequest, options); // serializes as expected
public class ReadOnlyMemoryConverter : JsonConverter<ReadOnlyMemory<byte>>
{
public override ReadOnlyMemory<byte> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> throw new NotImplementedException();
public override void Write(Utf8JsonWriter writer, ReadOnlyMemory<byte> value, JsonSerializerOptions options)
=> throw new NotImplementedException();
} |
FWIW this is simply surfacing a deeper issue with how the metadata model is interpreting JsonSerializer.Serialize(new MyPoco(), MyContext.Default.MyPoco);
[JsonSerializable(typeof(MyPoco))]
public partial class MyContext : JsonSerializerContext { }
public class MyPoco
{
[JsonIgnore]
public ReadOnlyMemory<byte> Memory { get; set; }
}
Root cause is essentially the same -- the source generator is eagerly attempting to generate metadata for the type even though it is ignored by the user. |
Seems we have checks preventing from throwing: and but we somehow ended up bypassing them |
These checks specifically validate whether the property is a valid type argument (i.e. not a pointer, ref struct, etc) and suppressing custom converter factory exceptions, but nothing more. This wasn't changed in .NET 7, what did change is eager resolution of JsonTypeInfo for all configured JsonPropertyInfo, including those that are marked as ignored. |
A fix for this is important - we serviced for this same scenario in .NET 6.0: #60299. |
Curious that regression testing didn't catch it. |
Re-opening till it's fixed in 7.0: #76869. |
I wonder if this is equivalent to this issue I'm hitting with this code: [JsonSerializable(typeof(MyObject))]
[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Metadata, IgnoreReadOnlyFields = true)]
internal partial class MyObjectSerializationContext : JsonSerializerContext
{
}
public class MyObject
{
[JsonPropertyName("test")]
public string? Test { get; set; }
[JsonIgnore]
private readonly ComplexObject? _data; // Metadata generated for this type. Why?!?
}
public class ComplexObject
{
private protected object _thisLock = new object(); // This causes code gen problem
} This will give me errors like:
I don't get why it is even trying to generate anything for In my specific case, |
It appears to be the same problem as #76807 (comment). Could you create a new issue with the problem? This one is specifically tracking the .NET 7 regression of the reflection serializer. |
@eiriktsarpalis Thanks - logged #76937 |
The failure and fix then were for the source generation implementation; tests should have been added for reflection as well. |
Description
JsonSerializer.Serialize(..)
method works differently in .NET 6 and in .NET 7 forReadOnlyMemory<byte>
property with[JsonIgnore]
attribute.Reproduction Steps
The issue can be reproduced using the following two files
JsonSerializerRepro.csproj
:Program.cs
:Expected behavior
When run as .NET 6 project, I get:
{"Upgrade":true}
Actual behavior
When run as .NET 7 project (RC1), I get:
Regression?
Maybe it's a regression. I'm not sure.
Known Workarounds
Implement custom JSON converter
Configuration
Tested on Windows 11. However, I don't believe it's a platform-specific issue.
Other information
No response
The text was updated successfully, but these errors were encountered: