c# - 在自定义 JsonConverter 中使用来自 json 的另一个属性
问题描述
假设以下 JSON:
{
"channel": "751853588527054938"
"message": "751853745758928908"
}
以及以下部分代码:
[JsonConverter(typeof(TextChannelConverter))]
[JsonProperty("channel")]
public ITextChannel Channel;
[JsonConverter(typeof(UserMessageConverter))]
[JsonProperty("message")]
public IUserMessage Message;
我想要做的是,我想为这两种类型的去实现一个自定义转换器,但问题是,如果我只有它的 ID,我无法收到消息,我还需要知道这样做的通道 ID(更准确地说,使用 ITextChannel#GetMessageAsync(ulong id) 检索消息)。有没有办法在 UserMessageConverter 中访问通道的 ID 甚至通道对象?
我尝试从阅读器加载整个 JSON
class UserMessageConverter : JsonConverter
{
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
public override bool CanConvert(Type objectType) => objectType == typeof(IUserMessage);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jobj = JObject.Load(reader);
return null;
}
但它发出一个例外:
Newtonsoft.Json.JsonReaderException: Error reading JObject from JsonReader. Current JsonReader item is not an object: Integer. Path 'message', line 1, position 75.
作为参考,TextChannelConverter的代码:
class TextChannelConverter : JsonConverter
{
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
public override bool CanConvert(Type objectType) => objectType == typeof(ITextChannel);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null)
return null;
ulong channelid = ulong.Parse(reader.Value.ToString());
return Essentials.FireLands.GetChannel(channelid);
}
解决方案
如果其中一个属性依赖于另一个,那么您需要制作一个JsonConverter
处理父对象的单一属性,而不是为每个子属性创建两个单独的转换器。
你没有说什么类包含你的模型中的Channel
andMessage
属性,所以我只是Chat
为了举例而称它为。
所以你会有:
[JsonConverter(typeof(ChatConverter))]
class Chat
{
public ITextChannel Channel { get; set; }
public IUserMessage Message { get; set; }
}
然后你的转换器可能看起来像这样:
class ChatConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(Chat);
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null)
return null;
JObject obj = JObject.Load(reader);
ulong channelId = (ulong)obj["channel"];
ulong messageId = (ulong)obj["message"];
ITextChannel channel = Essentials.FireLands.GetChannel(channelId);
IUserMessage = channel.GetMessageAsync(messageId).Result;
return new Chat { Channel = channel, Message = message };
}
}
推荐阅读
- ios - WKWebView swiftUI 在第二次尝试时崩溃
- laravel - Laravel 事件和监听器
- python - Python Pandas:对每一行应用一个特定的函数
- docker - 在基于 Alpine 的 Docker 映像中安装 Sdkman
- vue.js - 在 3 个项目(.net core、vue.js 和 webapi)中构建解决方案时会出现什么陷阱或后果?
- behat - 使用 Behat/Mink,如何匹配一个确切的数字?
- php - 如何将存储在数据库中的 Base64 字符串集合转换为普通图像存储在本地目录中
- angular - 将订单信息保存到两个表 - 角度 8
- javascript - 我怎样才能制作一个直接进入另一个视差的卷轴?
- python - python将十六进制字符串编码/解码为utf-8字符串