gpt4 book ai didi

asp.net-core - 使用自定义 JSON.NET JsonConverter 从 DescriptionAttribute 反序列化枚举停止工作

转载 作者:行者123 更新时间:2023-12-04 10:52:34 25 4
gpt4 key购买 nike

在 asp.net core 2.2 上寻找 Newtonsoft Json 的帮助。
我有一个 JsonEnumConverter<T>它负责序列化/反序列化来自 Enum 类型的 DescriptionAttribute 的值。直到大约 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。如果我在 JsonEnumConverter 的 ReadJson 中放置一个断点,它甚至不会命中。甚至尝试在启动时设置 JsonSerializerSettings ,但没有成功或运气。已经尝试用 EnumMember 和 StringEnumConverter 替换 Description。还是一样的问题。 ModelBinder 和 Json.NET 似乎存在一些问题,不能很好地相互配合。

注意:此问题发生在 ASP.NET Core 2.2 上。建议 3.0 的解决方案没有帮助!!

最佳答案

如果你使用的是aspnet core 3/netstandard 2.1,你可以试试这个库https://github.com/StefH/System.Text.Json.EnumExtensions它定义了 JsonStringEnumConverter 的一些扩展,以支持 EnumMember、Display 和 Description 等属性。

关于asp.net-core - 使用自定义 JSON.NET JsonConverter 从 DescriptionAttribute 反序列化枚举停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59403305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com