Заставить десериализатор JSON различать класс и подкласс этого класса

В приложении asp.net core mvc, над которым я работаю, я использую сеансы для отслеживания списка экземпляров модели, которую я создал под названием «Правило».

Теперь вы не можете сохранять объекты, кроме строк и целых чисел, в сеансах, я почти уверен, поэтому я написал расширение сеанса, которое сериализует и десериализует объекты, чтобы я мог сохранять их в сеансе.

Основная проблема, с которой я сталкиваюсь, заключается в том, что правило может содержать либо «карту», ​​у которой просто лицевая сторона, либо «мастную карту», ​​которая наследует карту, а также имеет масть.

Поэтому, когда я сериализую, а затем десериализую список, все карты SuitedCards превращаются в карты (в результате чего масти карт исчезают), я предполагаю, что это модель по умолчанию.

Как мне это исправить? Есть ли что-то, что я могу добавить к расширению сеанса, что поможет отличить, или это безнадежное дело?

Перед тем, как попробовать это с подклассами, я пытался сделать то же самое, используя интерфейсы, но проблема в том, что расширение сеанса пытается создать экземпляр интерфейса, что вызывает ошибки.

Расширение сеанса

    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);
        }

Когда я добавляю новое правило в список и страница обновляется, все правила, которые раньше содержали карты SuitedCard, теперь содержат обычные карты. Они должны оставаться SuitedCards.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
45
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ты пробовал

public static void Set<T>(this ISession session, string key, T value)
{
    session.SetString(key, JsonConvert.SerializeObject(value, new 
    JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }));
}

Это будет включать имена классов в Json, поэтому это поможет лучше идентифицировать типы во время десериализации.

Да, это сделало это для меня

Niels Boelens 10.06.2019 17:26

Другие вопросы по теме