简体   繁体   English

如何使用Azure Redis会话状态提供程序在ASP.NET会话中存储集合

[英]How to store a collection in ASP.NET Session using Azure Redis Session State Provider

I am using Microsoft.Web.Redis.RedisSessionStateProvider with Redis Cache configured on Azure, in ASP.NET MVC 5 application. 我在ASP.NET MVC 5应用程序中使用Microsoft.Web.Redis.RedisSessionStateProvider和Azure上配置的Redis缓存。

And I'm talking about storing values in Session in some action defined in controller. 我说的是在控制器中定义的某些操作中将值存储在Session中。 It works fine if I store primitive values ( Session["Foo"]="Bar" ) or collection of primitives: 如果我存储原始值( Session["Foo"]="Bar" )或原始集,则可以正常工作:

List<int> items = new List<int>();
items.Add(5);
Session["Items"] = items;

But if I try to store collection of my own class, it doesn't persist (after another request, Session["Products"] is null ): 但是,如果我尝试存储自己的类的集合,则该集合不会持续存在(在另一个请求之后, Session["Products"]null ):

List<Product> products = new List<Product>();
products.Add(db.Find(Id));
Session["Products"] = products;

Class Product looks like that: 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; }
}

What should I do to store instances of this class in session? 我应该怎么做才能在会话中存储此类的实例?

Since Redis is a Key-Value store, your objects need to be serialized to a byte[] stream. 由于Redis是键值存储,因此您的对象需要序列化为byte[]流。 Try to decorate your Product class with the [Serializable] attribute. 尝试使用[Serializable]属性装饰您的Product类。

See MSDN . 参见MSDN

@lort, I think the problem you might be facing is the following. @lort,我认为您可能会遇到以下问题。 The session dictionary in Redis when using Redis session state provider is itself a Hash where each session key value pair is a hash field/value pair and can take only strings as values and NOT objects such as lists as far as I know . 使用Redis会话状态提供程序时,Redis中的会话字典本身就是一个哈希,其中每个会话键值对都是一个哈希字段/值对,据我所知,只能将字符串作为值,而不能将诸如列表之类的对象作为对象 As @haim770 pointed out, you can convert the list into something like JSON or XML and write that JSON/XML as a string. 正如@ haim770指出的那样,您可以将列表转换为JSON或XML之类的内容,并将该JSON / XML作为字符串编写。 When you want to use the Session variable (that list), convert the JSON/XML string value back to list. 当您要使用Session变量(该列表)时,请将JSON / XML字符串值转换回list。

For example, see below.I am using Microsoft Redis Session State provider Microsoft.Web.Redis.RedisSessionStateProvider . 例如,请参阅下文。我正在使用Microsoft Redis会话状态提供程序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;

In redis-cli window, I can see the session value for list of products displayed. 在redis-cli窗口中,我可以看到显示的产品列表的会话值。 Please note that the session dictionary is a Redis Hash and each "entry" is one Hash field. 请注意,会话字典是Redis哈希,每个“条目”是一个哈希字段。

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"

Hope this helps (the OP or maybe someone else) although the question is old. 希望这个问题(OP或其他人)有所帮助,尽管问题仍然存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM