我有一个类型,我只需要在JSON和该类型的选定私有字段之间来回传递,忽略所有其他字段和属性,无论是公共的还是私有的。如何使用Json.NET实现这一点?
我目前的方法是使用一个中间的Dictionary<string, object>
。序列化有效,但反序列化无效
- 对于序列化,我向我的类型添加了一个方法,该方法构造一个
Dictionary<string, object>
,并按名称用必需的字段填充它。后来,我把字典序列化了。
这个很管用。
- 对于反序列化,我将反序列化为
Dictionary<string, object>
,然后尝试使用反射按名称和值填充我的类型的字段。
这不起作用,因为字典中的object
值的类型错误。
我该如何解决此问题?
范例类别:
public partial class MyClass
{
// Parameters is a instance of class which is created for storing some values.
private Dictionary<string, Parameters> SomeParameters;
private NotificationList notifications ;
private string someKey;
private int someNumber;
private char aChar;
public MyClass() { }
public MyClass(Dictionary<string, Parameters> someParameters, NotificationList notifications, string someKey, int someNumber, char aChar) =>
(this.SomeParameters, this.notifications, this.someKey, this.someNumber, this.aChar) = (someParameters, notifications, someKey, someNumber, aChar);
//...
//other properties and fields which should not be [de]serialized for this specific operation.
public string IgnoreMe { get; set; } = "ignore me";
private string alsoIgnoreMe = "ignore me";
}
public record Parameters(string Key, string Value);
public class NotificationList : List<string> { }
字符串
用于创建我的字典并从字典中重新创建MyClass
的示例类方法:
public partial class MyClass
{
public Dictionary<string, object> ToDictionary() => new()
{
{ nameof(SomeParameters), SomeParameters},
{ nameof(notifications), notifications },
{ nameof(someKey), someKey },
{ nameof(someNumber), someNumber },
{ nameof(aChar), aChar },
};
public static MyClass FromDictionary(Dictionary<string, object> settings)
{
var instance = new MyClass();
foreach (string settingValue in settings.Keys)
{
Type type = typeof(Dictionary<string, object>);
FieldInfo? fieldInfo = type.GetField(settingValue, BindingFlags.NonPublic | BindingFlags.Instance);
// This does not work -- fieldInfo is null, and settings[settingValue] is not the correct type.
fieldInfo?.SetValue(instance, settings[settingValue]);
}
return instance;
}
}
型
JSON示例:
{
"SomeParameters": {
"name": {
"Key": "hello",
"Value": "There"
}
},
"notifications": [],
"someKey": "some key",
"someNumber": 101,
"aChar": "z"
}
型
所以key(string)是我的字段名,object是字段值本身。序列化没有问题,但是我无法将object
(值)反序列化回原始类型。我找了很多,找不到任何简单的解决办法。
注意:我不能将这些变量放在类中并反序列化回去。特别是我需要在那个类里面做这个操作,并把值设置回去。必须分别为每个字段执行此操作。
演示小提琴here。
3条答案
按热度按时间x6492ojm1#
您的
FromDictionary()
方法需要两个修复:type.GetField(settingValue, ...)
时,您使用的类型必须是typeof(MyClass)
,而不是typeof(Dictionary<string, object>)
。这可以通过以下方式完成:
字符串
使用以下扩展方法:
型
演示小提琴#1 here。
作为替代方案,如果您只需要序列化和反序列化某些类型的特定(可能是私有)字段,您可以直接使用自定义合约解析器来完成此操作。使用一个完全消除了对一些中间
Dictionary<string, object>
的需要,因此避免了在反序列化时以某种方式猜测值对象的类型的需要。首先定义以下解析器:
型
然后,修改
MyClass
如下:型
现在,您将能够在所选字段与JSON之间进行往返,如下所示:
型
演示小提琴#2 here。
balp4ylt2#
你的代码很马虎。只要使用这个FromDictionary代码
字符串
并将带有参数的构造函数标记为[JsonConstructor]
型
IMHO
型
我从来没有从收藏继承中看到过什么好的
j7dteeu83#
首先感谢dbc提供了很大的帮助。我从他的回答中更新了我的需求。
首先,我简短地问“我如何反序列化并设置回MyClass的示例”,但设置回示例不起作用。所以我稍微改变了一下方式。现在我不反序列化到示例,而是通过
this
将巴克反序列化到类示例本身。这是我需要[反]序列化的类。SaveSettings将参数发送到它的重载方法。重载方法接受参数并添加字段名称,字段类型(字段类型转换为字符串表示)和最后字段的值到
settings
字典中,其中包含所有字段变量。添加所有字段/属性后,唯一要做的就是序列化并保存到磁盘。
当涉及到反序列化时,字段的名称,它的类型和字段值(内容)被设置回类内部,如下所示:
fieldInfo?.SetValue(this,ConvertToType(settings[settingValue].Value,typeOfObject))
我从dbc中获取了
ConvertToType
方法我通过以下方式来确定磁场类型
Type.GetType(settings[settingValue].Key);
这可以检索存储在磁盘中的字符串类型。(简单地说,字符串到类型,类型到字符串)
字符串