使 JSON 反序列化器区分 class 和 class 的子 class
Make JSON deserialiser distinguish between a class and a subclass of that class
在我正在处理的 asp.net 核心 mvc 应用程序中,我使用会话来跟踪我创建的名为 "Rule".
的模型的实例列表
现在,你不能在会话中保存字符串和整数以外的对象,我很确定,所以我写了一个会话扩展来序列化和反序列化对象,这样我就可以将它们保存在会话中。
我 运行 遇到的主要问题是规则可以包含仅具有牌面的 "Card" 或 "SuitedCard",它继承了 Card 并具有牌套。
因此,当我序列化然后反序列化列表时,所有 SuitedCards 变成卡片(导致卡片套装消失),我假设因为这是模型的默认值。
我该如何解决这个问题?我可以在会话扩展中添加一些有助于区分的东西,还是这是一个失败的原因?
在用子类尝试这个之前,我尝试使用接口做同样的事情,但问题是会话扩展试图实例化接口,这会导致错误。
SessionExtention
public static class SessionExtentions
{
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value== null ? default(T):
JsonConvert.DeserializeObject<T>(value);
}
}
控制器中的规则列表
private List<Rule> _ruleList;
private List<Rule> RuleList
{
get
{
if (_ruleList == null)
_ruleList = HttpContext.Session.Get<List<Rule>>("RuleList");
return _ruleList;
}
set
{
_ruleList = value;
HttpContext.Session.Set("RuleList", _ruleList);
}
}
我将项目添加到列表的操作
[HttpPost()]
public IActionResult CreateRuleSet (CreateRuleSetViewModel model)
{
if (RuleList == null)
{
RuleList = MockDb;
}
List<Rule> rules = new List<Rule>();
rules.AddRange(RuleList);
Card card = new Card();
if (model.CheckBox)
{
card = new SuitedCard(model.Face, model.Suit);
}
else
{
card.Face = model.Face;
}
rules.Add((new Rule(card, model.Type, 0)));
RuleList = rules;
model.Rules = rules;
return View(model);
}
当我向列表添加新规则并且页面刷新时,所有用于包含 SuitedCards 的规则现在都包含常规卡片。他们应该保持 SuitedCards。
你试过了吗
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value, new
JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }));
}
这将在 Json 中包含 class 名称,因此有助于在反序列化过程中更好地识别类型。
在我正在处理的 asp.net 核心 mvc 应用程序中,我使用会话来跟踪我创建的名为 "Rule".
的模型的实例列表现在,你不能在会话中保存字符串和整数以外的对象,我很确定,所以我写了一个会话扩展来序列化和反序列化对象,这样我就可以将它们保存在会话中。
我 运行 遇到的主要问题是规则可以包含仅具有牌面的 "Card" 或 "SuitedCard",它继承了 Card 并具有牌套。
因此,当我序列化然后反序列化列表时,所有 SuitedCards 变成卡片(导致卡片套装消失),我假设因为这是模型的默认值。
我该如何解决这个问题?我可以在会话扩展中添加一些有助于区分的东西,还是这是一个失败的原因?
在用子类尝试这个之前,我尝试使用接口做同样的事情,但问题是会话扩展试图实例化接口,这会导致错误。
SessionExtention
public static class SessionExtentions
{
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value== null ? default(T):
JsonConvert.DeserializeObject<T>(value);
}
}
控制器中的规则列表
private List<Rule> _ruleList;
private List<Rule> RuleList
{
get
{
if (_ruleList == null)
_ruleList = HttpContext.Session.Get<List<Rule>>("RuleList");
return _ruleList;
}
set
{
_ruleList = value;
HttpContext.Session.Set("RuleList", _ruleList);
}
}
我将项目添加到列表的操作
[HttpPost()]
public IActionResult CreateRuleSet (CreateRuleSetViewModel model)
{
if (RuleList == null)
{
RuleList = MockDb;
}
List<Rule> rules = new List<Rule>();
rules.AddRange(RuleList);
Card card = new Card();
if (model.CheckBox)
{
card = new SuitedCard(model.Face, model.Suit);
}
else
{
card.Face = model.Face;
}
rules.Add((new Rule(card, model.Type, 0)));
RuleList = rules;
model.Rules = rules;
return View(model);
}
当我向列表添加新规则并且页面刷新时,所有用于包含 SuitedCards 的规则现在都包含常规卡片。他们应该保持 SuitedCards。
你试过了吗
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value, new
JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }));
}
这将在 Json 中包含 class 名称,因此有助于在反序列化过程中更好地识别类型。