在 MVC 中跨页面存储通用日期 ASP.NET

本文关键字:日期 ASP NET 存储 MVC | 更新日期: 2023-09-27 18:31:14

我使用基本控制器和OnActionExecute来获取我想在大多数页面中显示和保留的"通用"站点数据(名称,ID等......不超过4/5字段)

OnActionExecute中的方法读取数据库并保存到ViewBag中,我在我的视图中选择了它,但我忍不住认为这是一种浪费,因为它需要为每个OnActionExecuting调用数据库。

如何协调这些数据库调用并减少数据库访问?

在 MVC 中跨页面存储通用日期 ASP.NET

我在最近的一个项目中所做的是在登录期间我获得了"通用"数据,在这种情况下是UserID,FirstName和ImageName,我将其保存在身份验证票证中,如下所示:

UserData = pModel.PartyId.ToString() + "|" + pModel.BusinessName + "|" + pModel.FirstName + "|" + pModel.LastName + "|" + pModel.ImageUrl + "|" + UsersRole + "|" + IsAct;//PID, BusName, FirstName, LastName, imgUrl, Role, IsAct
// Create the cookie that contains the forms authentication ticket
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(UN, true);
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, UserData);
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);

然后,当需要数据时,我会检索此 Cookie,并像这样从中获取数据:

var cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName];
dynamic UN = FormsAuthentication.Decrypt(cookie.Value);
string UserData = UN.UserData;//PID, BusName, FirstName, LastName, imgUrl, Role, IsAct
string[] pFields = UserData.Split('|');
string[] MyRoles = { pFields[5] };

请注意:这仅适用于您知道在登录会话期间不会更改的静态数据,并小心您在此 Cookie 中发布的内容。

不要使cookie膨胀,也不要将字段保持在最小值,最大值为4K,但我的目标是500-1000字节。

将通用数据值缓存在存储库层中。

您可以使用 System.Runtime.Caching.MemoryCache 来实现此目的。

一些例子:

  • http://stevescodingblog.co.uk/net4-caching-with-mvc/
  • http://msprogrammer.serviciipeweb.ro/tag/memorycache/
缓存

将跨请求保留,直到达到每个缓存项的过期时间。

从基本控制器继承并不意味着您在请求之间具有共享状态。每个请求都会生成一个新的控制器实例。

如果您不想每次都检索此数据,则需要将此数据存储在某种状态(缓存、会话、应用程序)中。然后,您可以从基本控制器访问存储它的任何机制。

然后是免责声明...这些数据库访问费用高吗?您是否打算用最小延迟问题换取内存管理问题?

更新:

如果它只有 4-5 个字段(似乎是特定于用户的,并且它们在用户会话期间不会更改),那么我只会将它们存储在会话状态中。

这里的个人偏好,但我喜欢在基本控制器/页面中使用强类型访问器,如下所示:

    protected string Name
    {
        get
        {
            if (Session["Name"] == null)
            {
                var results = GoLoadFields();                    
                return Session["Name"].ToString();
            }
            return Session["Name"].ToString();
        }
        set
        {
            Session["Name"] = value;
        }
    }

然后,在从基本控制器继承的所有控制器中,只需引用以下属性:

myAwesomeViewModel.Name = this.Name;

内存管理免责声明旨在让您避免查询数据库、获取相同的大型结果集并将其推入每个用户的会话中。在将任何内容保留在内存中之前,只需确保只保留所需的内容以及需要多长时间。