gpt4 book ai didi

c# - Json.Net 在使用我的 JsonConverter 之前自行转换

转载 作者:太空宇宙 更新时间:2023-11-03 10:24:45 24 4
gpt4 key购买 nike

在我的 WPF 代码中,我使用 Newtonsoft.Json 将 json 反序列化到我的模型中。首先,我收到一个 Json 字符串 ('json'),然后将其解析为 'message'。 (我要反序列化的对象包装在 json 字符串中的“数据”字段中)。

Activity message = JObject.Parse(json)["data"].ToObject<Activity>();

我的 Activity 类使用多个 [JsonProperty] 属性来生成其字段。其中之一是名为“ActivityType”的枚举。

[JsonProperty("type")]
[JsonConverter(typeof(ActivityTypeConverter))]
public ActivityType Type { get; set; }

public enum ActivityType {
EmailOpen,
LinkClick,
Salesforce,
Unsupported
};

public class ActivityTypeConverter : JsonConverter {

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var rawString = existingValue.ToString().ToLower();
if (rawString.Contains("click"))
return ActivityType.LinkClick;
else if (rawString.Contains("salesforce"))
return ActivityType.Salesforce;
else if (rawString.Contains("email_open"))
return ActivityType.EmailOpen;
else
{
Console.WriteLine("unsupported " + rawString);
return ActivityType.Unsupported;
}
}

public override bool CanConvert(Type objectType)
{
return !objectType.Equals(typeof(ActivityType));
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

奇怪和令人沮丧的是,我知 Prop 有“type”:“email_open”的 json 对象被反序列化为 ActivityType.Unsupported,即使我的转换器应该将它们反序列化为 EmailOpen。​​

调试显示问题所在:json 字段“type”自动将“email_open”反序列化为 EmailOpen 然后它通过我的转换器发送。 (然后它中断了,因为我的条件检查下划线,而 EmailOpen.ToString() 没有下划线。)


那么我的问题是:为什么它在没有我的转换器的情况下进行转换,我该如何停止它?我只希望它只使用我的转换器

最佳答案

我认为您的转换器正在被调用——它只是不工作。问题在于,您不是从 JsonReader 阅读器 读取新值,而是使用 existingValue 中的值。但是这第二个值是被反序列化的类中预先存在的属性值,不是被读取的值。

您需要按照 Json.NET 的 StringEnumConverter 从读取器加载值.下面是一个版本,它通过子类化 StringEnumConverter 并将从文件读取的值传递给基类以进行进一步处理来处理枚举的标准值:

public class ActivityTypeConverter : StringEnumConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
bool isNullable = (Nullable.GetUnderlyingType(objectType) != null);
Type type = (Nullable.GetUnderlyingType(objectType) ?? objectType);

if (reader.TokenType == JsonToken.Null)
{
if (!isNullable)
throw new JsonSerializationException();
return null;
}

var token = JToken.Load(reader);
if (token.Type == JTokenType.String)
{
var rawString = ((string)token).ToLower();
if (rawString.Contains("click"))
return ActivityType.LinkClick;
else if (rawString.Contains("salesforce"))
return ActivityType.Salesforce;
else if (rawString.Contains("email_open"))
return ActivityType.EmailOpen;
}

using (var subReader = token.CreateReader())
{
while (subReader.TokenType == JsonToken.None)
subReader.Read();
try
{
return base.ReadJson(subReader, objectType, existingValue, serializer); // Use base class to convert
}
catch (Exception ex)
{
return ActivityType.Unsupported;
}
}
}

public override bool CanConvert(Type objectType)
{
return objectType == typeof(ActivityType);
}
}

关于c# - Json.Net 在使用我的 JsonConverter 之前自行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32017695/

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