Нужна помощь с Newtonsoft Json на ядре asp.net 2.2. У меня есть JsonEnumConverter<T>
, который отвечал за сериализацию/десериализацию значений из DescriptionAttribute из типа Enum. Примерно 2 недели назад все работало нормально, а сейчас вообще перестало работать.
вот что у меня есть:
//From PerformersController:
public async Task<ActionResult<PagedPerformers>> GetPagedPerformersAsync([FromQuery] PerformerRequest performerRequest) { ... }
[JsonObject]
public class PerformerRequest : PageRequest
{
[FromQuery(Name = "performer_id")]
[JsonProperty(PropertyName = "performer_id", Order = 1)]
public override string Id { get; set; }
....
}
[JsonConverter(typeof(JsonEnumConverter<SortDirectionType>))]
public enum SortDirectionType
{
[Description("asc")]
ASCENDING,
[Description("desc")]
DESCENDING
}
public abstract class PageRequest
{
[FromQuery(Name = "page")]
[JsonProperty("page")]
public int Page { get; set; }
[FromQuery(Name = "limit")]
[JsonProperty("limit")]
public int PageSize { get; set; } = 100;
[FromQuery(Name = "sort_field")]
[JsonProperty("sort_field")]
public string SortField { get; set; } //= "Id";
[FromQuery(Name = "sort_dir")] [JsonConverter(typeof(JsonEnumConverter<SortDirectionType>))]
[JsonProperty("sort_dir")]
public SortDirectionType SortDirection { get; set; }
[FromQuery(Name = "id")]
[JsonProperty("id")]
public virtual string Id { get; set; }
}
public class JsonEnumConverter<T> : JsonConverter where T : struct, IComparable, IConvertible, IFormattable
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(T);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var type = typeof(T);
if (!type.IsEnum) throw new InvalidOperationException();
var enumDescription = (string)reader.Value;
return enumDescription.GetEnumValueFromDescription<T>();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var type = typeof(T);
if (!type.IsEnum) throw new InvalidOperationException();
if (value != null)
{
if (value is Enum sourceEnum)
{
writer.WriteValue(sourceEnum.GetDescriptionFromEnumValue());
}
}
}
}
public static class EnumExtensions
{
public static string GetDescriptionFromEnumValue(this Enum @enum)
{
FieldInfo fi = @enum.GetType().GetField(@enum.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return @enum.ToString();
}
public static T GetEnumValueFromDescription<T>(this string description)
{
var type = typeof(T);
if (!type.IsEnum)
throw new InvalidOperationException();
foreach (var field in type.GetFields())
{
if (Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) is DescriptionAttribute attribute)
{
if (attribute.Description == description)
return (T)field.GetValue(null);
}
else
{
if (field.Name == description)
return (T)field.GetValue(null);
}
}
throw new ArgumentException($"No matching value for enum {nameof(T)} found from {description}.",$"{nameof(description)}"); // or return default(T);
}
}
это работало абсолютно нормально до недавнего времени. Теперь я не уверен, что происходит, я сразу получаю ответ ValidationProblemDetails. Если я отключу недопустимый фильтр состояния модели asp.net core 2.2, тогда modelState.IsValid все равно будет иметь значение false. Если я поставлю точку останова в ReadJson моего JsonEnumConverter, она даже не сработает. Даже безуспешно пытался установить JsonSerializerSettings при запуске. Уже пробовали заменить Description на EnumMember и StringEnumConverter. Все та же проблема. Похоже, что есть проблема с ModelBinder и Json.NET, которые плохо взаимодействуют друг с другом.
ПРИМЕЧАНИЕ. Эта проблема возникает в ASP.NET Core 2.2. Предлагать решения для версии 3.0 бесполезно!!
<TargetFramework>netcoreapp2.2</TargetFramework>
. - person BRBdot   schedule 19.12.2019