Я использую Microsoft.Web.Redis.RedisSessionStateProvider
с Redis Cache, настроенным на Azure, в приложении ASP.NET MVC 5.
И я говорю о сохранении значений в Session
в некоторых действиях, определенных в контроллере. Он отлично работает, если я храню примитивные значения (Session["Foo"]="Bar"
) или набор примитивов:
List<int> items = new List<int>();
items.Add(5);
Session["Items"] = items;
Но если я пытаюсь сохранить коллекцию своего собственного класса, она не сохраняется (после другого запроса Session["Products"]
имеет значение null
):
List<Product> products = new List<Product>();
products.Add(db.Find(Id));
Session["Products"] = products;
Класс Product
выглядит следующим образом:
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
public int CategoryID { get; set; }
[ForeignKey("CategoryID")]
public Category Category { get; set; }
public decimal Price { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
Что делать, чтобы хранить экземпляры этого класса в сеансе?
Поскольку Redis является хранилищем Key-Value, ваши объекты должны быть сериализованы в поток byte[]
. Попробуйте украсить ваш класс Product
с помощью атрибута [Serializable]
.
См. MSDN.
@lort, я думаю, что проблема, с которой вы можете столкнуться, следующая. Словарь сеанса в Redis при использовании провайдера состояния сеанса Redis сам по себе является хэшем, где каждая пара значений ключа сеанса является хэш-полем/значением пары и может принимать только строки как значения и НЕ объекты, такие как списки, насколько я знаю. Как отметил @haim770, вы можете преобразовать список в нечто вроде JSON или XML и написать JSON/XML в виде строки. Если вы хотите использовать переменную Session (этот список), преобразуйте значение строки JSON/XML в список.
Например, см. Ниже. Я пользуюсь Microsoft Redis Session State provider Microsoft.Web.Redis.RedisSessionStateProvider.
JavaScriptSerializer ser = new JavaScriptSerializer();
List<Product> products = new List<Product>();
products.Add(new Product{Name="test", Description="test"});
string productsField = ser.Serialize(products);
Session["Products"] = productsField;
В окне redis-cli я вижу значение сеанса для списка отображаемых продуктов. Обратите внимание, что словарь сеанса - это Redis Hash, и каждая "запись" - одно поле Hash.
redis 127.0.0.1:6379> hgetall /SessionInRedis_nnl24530afhndnchb2f3ronc_Data
1) "loginTime"
2) "\x00\x01\x00\x00\x00\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x06\x01
\x00\x00\x00\x149/25/2014 7:52:03 PM\x0b"
3) "UserName"
4) "\x00\x01\x00\x00\x00\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x06\x01
\x00\x00\x00\x06prasad\x0b"
5) "Products"
6) "\x00\x01\x00\x00\x00\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x06\x01
\x00\x00\x00&[{\"Name\":\"test\",\"Description\":\"test\"}]\x0b"
Надеюсь, что это поможет (OP или, возможно, кому-то еще), хотя вопрос старый.
new List<Product>();
в другом классе, который помечен как[Serializable]
.