JsonConverterAttribute не используется JsonSerializer.C#

Место общения программистов C#
Ответить
Anonymous
 JsonConverterAttribute не используется JsonSerializer.

Сообщение Anonymous »

Я пытаюсь сериализовать свойство типа Encoding. Для этой цели я написал класс конвертера. Когда я использую JsonSerializerOptions, все работает, но когда я использую JsonConverterAttribute, я получаю исключение. Я не уверен, что делаю неправильно при использовании JsonConverterAttribute, поэтому надеюсь на вашу помощь.
Пример кода и исключения:
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace TestJsonConverterBug
{
internal class Program
{
static readonly JsonSerializerOptions _options = new();

static void Main()
{
_options.Converters.Add(new JsonEncodingConverter());

TestOptions();
TestAttributeSerialize();
TestAttributeDeserialize();
}

// WORKS WITH OPTIONS
static void TestOptions()
{
var obj = new SerializableClass1();

var json = JsonSerializer.Serialize(obj, _options);

var enc = JsonSerializer.Deserialize(json, _options);
}

// DOESN'T WORK WITH CONVERTER ATTRIBUTE
static void TestAttributeSerialize()
{
var obj = new SerializableClass2();

var json = JsonSerializer.Serialize(obj);
}

// DOESN'T WORK WITH CONVERTER ATTRIBUTE
static void TestAttributeDeserialize()
{
var obj = new SerializableClass2();

var json = JsonSerializer.Serialize(obj, _options);

var enc = JsonSerializer.Deserialize(json);
}
}

internal class SerializableClass1
{
public SerializableClass1()
{
Encoding = Encoding.ASCII;
}

public Encoding Encoding { get; set; }
}

internal class SerializableClass2
{
public SerializableClass2()
{
Encoding = Encoding.ASCII;
}

[JsonConverter(typeof(JsonEncodingConverter))]
public Encoding Encoding { get; set; }
}

internal class JsonEncodingConverter : JsonConverter
{
public override bool CanConvert(Type typeToConvert)
=> typeToConvert.IsAssignableTo(typeof(Encoding));

public override Encoding? Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options
) => Encoding.GetEncoding(reader.GetString()!);

public override void Write(
Utf8JsonWriter writer,
Encoding value,
JsonSerializerOptions options
) => writer.WriteStringValue(value.EncodingName);
}
}

Исключение TestAttributeSerialize:
System.InvalidOperationException
HResult=0x80131509
Message=The type 'System.ReadOnlySpan`1[System.Byte]' of property 'Preamble' on type 'System.Text.Encoding' is invalid for serialization or deserialization because it is a pointer type, is a ref struct, or contains generic parameters that have not been replaced by specific types.
Source=System.Text.Json
StackTrace:
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_CannotSerializeInvalidType(Type typeToConvert, Type declaringType, MemberInfo memberInfo)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.CreatePropertyInfo(JsonTypeInfo typeInfo, Type typeToConvert, MemberInfo memberInfo, JsonSerializerOptions options, Boolean shouldCheckForRequiredKeyword, Boolean hasJsonIncludeAttribute)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.AddMembersDeclaredBySuperType(JsonTypeInfo typeInfo, Type currentType, Boolean constructorHasSetsRequiredMembersAttribute, PropertyHierarchyResolutionState& state)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.PopulateProperties(JsonTypeInfo typeInfo)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.CreateTypeInfoCore(Type type, JsonConverter converter, JsonSerializerOptions options)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.GetTypeInfo(Type type, JsonSerializerOptions options)
at System.Text.Json.JsonSerializerOptions.GetTypeInfoNoCaching(Type type)
at System.Text.Json.JsonSerializerOptions.CachingContext.CreateCacheEntry(Type type, CachingContext context)
--- End of stack trace from previous location ---
at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Nullable`1 ensureNotNull, Boolean resolveIfMutable, Boolean fallBackToNearestAncestorType)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo.Configure()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.ConfigureProperties()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.g__ConfigureSynchronized|172_0()
at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Nullable`1 ensureNotNull, Boolean resolveIfMutable, Boolean fallBackToNearestAncestorType)
at System.Text.Json.JsonSerializerOptions.GetTypeInfoForRootType(Type type, Boolean fallBackToNearestAncestorType)
at System.Text.Json.JsonSerializer.GetTypeInfo[T](JsonSerializerOptions options)
at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
at TestJsonConverterBug.Program.TestAttributeSerialize() in ...\TestJsonConverterBug\Program.cs:line 35
at TestJsonConverterBug.Program.Main() in ...\TestJsonConverterBug\Program.cs:line 16

Исключение TestAttributeDeserialize:
System.InvalidOperationException
HResult=0x80131509
Message=The type 'System.ReadOnlySpan`1[System.Byte]' of property 'Preamble' on type 'System.Text.Encoding' is invalid for serialization or deserialization because it is a pointer type, is a ref struct, or contains generic parameters that have not been replaced by specific types.
Source=System.Text.Json
StackTrace:
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_CannotSerializeInvalidType(Type typeToConvert, Type declaringType, MemberInfo memberInfo)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.CreatePropertyInfo(JsonTypeInfo typeInfo, Type typeToConvert, MemberInfo memberInfo, JsonSerializerOptions options, Boolean shouldCheckForRequiredKeyword, Boolean hasJsonIncludeAttribute)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.AddMembersDeclaredBySuperType(JsonTypeInfo typeInfo, Type currentType, Boolean constructorHasSetsRequiredMembersAttribute, PropertyHierarchyResolutionState& state)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.PopulateProperties(JsonTypeInfo typeInfo)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.CreateTypeInfoCore(Type type, JsonConverter converter, JsonSerializerOptions options)
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.GetTypeInfo(Type type, JsonSerializerOptions options)
at System.Text.Json.JsonSerializerOptions.GetTypeInfoNoCaching(Type type)
at System.Text.Json.JsonSerializerOptions.CachingContext.CreateCacheEntry(Type type, CachingContext context)
--- End of stack trace from previous location ---
at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Nullable`1 ensureNotNull, Boolean resolveIfMutable, Boolean fallBackToNearestAncestorType)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo.Configure()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.ConfigureProperties()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.g__ConfigureSynchronized|172_0()
at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Nullable`1 ensureNotNull, Boolean resolveIfMutable, Boolean fallBackToNearestAncestorType)
at System.Text.Json.JsonSerializerOptions.GetTypeInfoForRootType(Type type, Boolean fallBackToNearestAncestorType)
at System.Text.Json.JsonSerializer.GetTypeInfo[T](JsonSerializerOptions options)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at TestJsonConverterBug.Program.TestAttributeDeserialize() in ...\TestJsonConverterBug\Program.cs:line 45
at TestJsonConverterBug.Program.Main() in ...\TestJsonConverterBug\Program.cs:line 17


Подробнее здесь: https://stackoverflow.com/questions/783 ... serializer
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»