TL / DR: у вас есть две основные проблемы c:
. NET Core 3.0+ имеет новый встроенный JSON сериализатор System.Text.Json
, и вы смешиваете атрибуты и классы между этим новым сериализатором и Json. NET. Это очень легко сделать, когда оба установлены, потому что они имеют некоторые имена классов, такие как JsonSerializer
и JsonConverter
.
Новый сериализатор используется по умолчанию , но пока не поддерживает сериализацию перечислений в виде строк с именами пользовательских значений; см. System.Text. Json: Как указать пользовательское имя для значения перечисления? для подробностей.
Самый простой способ решить вашу проблему - переключиться обратно на Json. NET, как показано здесь и использовать атрибуты, преобразователи и пространства имен исключительно из этого сериализатора.
Сначала давайте разберем различия и сходства между двумя сериализаторами:
System.Text.Json
:
Json. NET:
Имея это в виду, какой сериализатор вы используете в своем коде? Поскольку вы любезно включили пространства имен в свой вопрос, мы можем проверить:
using System.Text.Json.Serialization; // System.Text.Json
using Newtonsoft.Json; // Json.NET
namespace Assignment_1
{
public class MyRequest
{
//...
[JsonProperty( // JsonProperty from Newtonsoft
"changeTypes",
ItemConverterType = typeof(JsonStringEnumConverter)// JsonStringEnumConverter from System.Text.Json
)]
public AppGlobals.BoardSymbols[] GameBoard { get; set; }
}
}
Итак, как вы можете видеть, вы смешиваете атрибуты из Newtonsoft с конвертерами из System.Text.Json
, что не будет работать , (Возможно, вы выбрали пространства имен из щелчка правой кнопкой мыши «Разрешить -> используя ...» в Visual Studio?)
Итак, как решить проблему? Поскольку Json. NET поддерживает переименование значений перечисления «из коробки», самый простой способ решить вашу проблему - использовать этот сериализатор. Хотя, возможно, он не такой производительный, как System.Text.Json
, он гораздо более полный и полнофункциональный.
Для этого удалить пространства имен System.Text.Json.Serialization
и System.Text.Json
и ссылки на тип JsonStringEnumConverter
из вашего кода и измените MyRequest
и BoardSymbols
следующим образом:
using System.Runtime.Serialization;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json;
namespace Assignment_1
{
public class MyRequest
{
//...
[Required]
[MinLength(9)]
[MaxLength(9)]
[JsonProperty("changeTypes")] // No need to add StringEnumConverter here since it's already applied to the enum itself
public AppGlobals.BoardSymbols[] GameBoard { get; set; }
}
}
namespace AppGlobals
{
[JsonConverter(typeof(StringEnumConverter))]
public enum BoardSymbols
{
[EnumMember(Value = "X")]
First = 'X',
[EnumMember(Value = "O")]
Second = 'O',
[EnumMember(Value = "?")]
EMPTY = '?'
}
}
Затем NuGet Microsoft.AspNetCore.Mvc.NewtonsoftJson
и в Startup.ConfigureServices
вызов AddNewtonsoftJson()
:
services.AddMvc()
.AddNewtonsoftJson();
Или, если вы предпочитаете использовать StringEnumConverter
в глобальном масштабе:
services.AddMvc()
.AddNewtonsoftJson(o => o.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()));
Обратите внимание на следующий комментарий из документов
Примечание: Если метод AddNewtonsoftJson
недоступен, убедитесь, что вы установили Microsoft.AspNetCore. Mvc .Newtonsoft Json. Распространенной ошибкой является установка пакета Newtonsoft. Json вместо Microsoft.AspNetCore. Mvc .Newtonsoft Json.
Макетная скрипка здесь .