c# - Newtonsoft C# 自定义 JsonConverter 不反序列化字节数组
问题描述
我正在尝试创建一个简单的 JsonConverter。我希望将我的字节数组序列化为数字数组,而不是默认的 base 64 字符串。但是,当我尝试这样做时,我得到了 JsonSerializationException。
这是我为简化问题而制作的课程:
public class SomethingFancy
{
string name;
byte[] usefulData;
public SomethingFancy(string name, byte[] usefulData)
{
this.Name = name;
this.UsefulData = usefulData;
}
public string Name { get => name; set => name = value; }
public byte[] UsefulData { get => usefulData; set => usefulData = value; }
}
现在这是我的自定义 Json 转换器。我试图让它只适用于 IEnumerable 对象。(默认情况下,序列化时 IEnumerable 转换为字符串,反序列化时反之亦然。我更改了该行为以将 IEnumerable 保存为 json 数字数组。
public class EnumerableByteConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
var result = typeof(IEnumerable<byte>).IsAssignableFrom(objectType);
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteValue(value);
}
else
{
byte[] bytes = ((IEnumerable<byte>)value).ToArray();
int[] ints = Array.ConvertAll(bytes, c => (int)c);
writer.WriteStartArray();
foreach (int number in ints)
{
writer.WriteValue(number);
}
writer.WriteEndArray();
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
int[] ints = (int[])reader.Value;
if (ints == null)
return default;
else
{
byte[] bytes = ints.SelectMany(BitConverter.GetBytes).ToArray();
if (objectType == typeof(byte[]))
{
return bytes;
}
var result = new List<byte>(bytes);
return result;
}
}
}
这是我为测试我的课程而编写的一些单元测试:
[TestClass]
public class PersistencyServiceTest
{
[TestMethod]
public void TestJsonSerializationDeserialization()
{
var settings = new JsonSerializerSettings();
settings.Converters.Add(new EnumerableByteConverter());
SomethingFancy something = new SomethingFancy("someName", new byte[3] { 1, 2, 3 });
string dataasstring = JsonConvert.SerializeObject(something, Formatting.Indented, settings);
something = JsonConvert.DeserializeObject<SomethingFancy>(dataasstring, settings);
Assert.IsTrue(something != null);
Assert.IsTrue(something.Name == "someName");
Assert.IsTrue(something.UsefulData != null);
Assert.IsTrue(something.UsefulData[0] == 1);
Assert.IsTrue(something.UsefulData[1] == 2);
Assert.IsTrue(something.UsefulData[2] == 3);
}
}
现在,它按照我的需要序列化我的对象。
{
"Name": "someName",
"UsefulData": [
1,
2,
3
]
}
但是,反序列化会引发 JsonSerializationException(反序列化对象时出现意外标记:整数。路径 'UsefulData[0],第 4 行,第 5 位)。
我错过了什么?
谢谢你的帮助。
解决方案
我用 ReadJson 方法做错了。
这是我遇到的同样问题的人的自定义 JsonConverter:
public class EnumerableByteConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
var result = typeof(IEnumerable<byte>).IsAssignableFrom(objectType);
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteValue(value);
}
else
{
byte[] bytes = ((IEnumerable<byte>)value).ToArray();
int[] ints = Array.ConvertAll(bytes, c => (int)c);
writer.WriteStartArray();
foreach (int number in ints)
{
writer.WriteValue(number);
}
writer.WriteEndArray();
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
List<int> ints = null;
if (reader.TokenType == JsonToken.Null)
return default;
while (reader.TokenType != JsonToken.EndArray)
{
if (reader.TokenType == JsonToken.StartArray)
{
ints = new List<int>();
reader.Read();
}
else if(reader.TokenType == JsonToken.Integer)
{
ints.Add(Convert.ToInt32(reader.Value));
reader.Read();
}
else
{
throw new InvalidOperationException();
}
}
if (ints == null)
return default;
else
{
byte[] bytes = Array.ConvertAll(ints.ToArray(), x => (byte)x);
if (objectType == typeof(byte[]))
{
return bytes;
}
var result = new List<byte>(bytes);
return result;
}
}
}
推荐阅读
- spring - 当我启用 swagger 时,spring boot 应用程序无法启动
- python - 在 Python Pandas 的 DataFrame 中使用日期进行数据操作?
- python - 我如何存储不和谐机器人 python 的信息
- python - 从 Python Counter() 结果中提取特定单词对的共现值的有效方法
- azure-devops-self-hosted-agent - 如何满足 Visual Studio 对自托管 docker 构建代理的需求?
- javascript - 在href中的函数不能使用javascript
- reactjs - 如何导航到 React Router 中的部分
- python - 获取数据集的无效行
- c# - C# & Entity Framework Core 创建实体多对多关系与自身作为多个父母和多个孩子
- ios - 如何使用 RxSwift 重新加载数据 UICollectionView?