在ASP.NET MVC中保留用户数据

时间:2012-05-15 05:59:24

标签: c# asp.net-mvc session-state

以前曾提出类似的问题,但我仍然没有答案,并花了相当多的时间试图找到一个。

情景就是这样。我们有一个ASP.NET MVC应用程序,它使用Forms Authentication / LINQ-to-SQL数据模型。

每个用户都可以与一个或多个帐户相关联。登录后,应用程序将检查与其关联的帐户数。

0 =转到错误页面,让他们知道他们没有访问权限 1 =设置用户数据以使用该帐户
2或更多 =转到允许他们选择要使用的帐户的页面(可以在访问期间更改)

您如何存储此信息?

此外,我想使用此帐户作为我的控制器操作的基础。即他们访问的后续页面上的数据将与他们选择的帐户相关。

想到单身 咳嗽 ,但我不确定如何实施。

我目前正在研究的一种方法是一个基本控制器,所有控制器都将继承该基础控制器

  1. 检查用户是否已登录。
  2. 如果是,请检查他们是否选择了帐户
    • 否 - 将其重定向到“帐户选择”页面
    • 是 - 继续原始请求
  3. 这样做的推荐/最佳实践方法是什么?

    由于 马尔科

2 个答案:

答案 0 :(得分:2)

请勿使用基本控制器。您可以使用操作过滤器完成此操作。这将为您提供拦截点,以检查他们是否已登录,是否已选择帐户,甚至将其重定向到错误或帐户选择页面。您所要做的就是在操作过滤器的filterContext.Result方法中设置OnActionExecuting,以防止请求通过。在操作期间,您可以完全访问会话,临时数据,cookie和整个HttpContext,就像在控制器中一样。您还可以使用过滤器属性过滤器提供程序注入依赖项属性,以便为您提供所需的任何数据访问权限。

就数据建模而言,我对Linq to SQL并不太熟悉,但我认为正常的一对应该可以做到这一点:

User (1) <-------> (0..*) Account

public class User
{
    public virtual ICollection<Account> Accounts { get; protected internal set; }
}

public class Account
{
    public int UserId { get; protected internal set; }
    public virtual User User { get; protected internal set; }
}

更新:抱歉,我误解了“商店”的含义。在MVC中,只有几种方法可以存储它 - Session,Cookie和Cache(以及TempData,它只是短期会话)是最受欢迎的选择。我的选择取决于。会话可能是最简单的,但如果您使用负载均衡器部署到服务器场,则需要考虑如果用户的会话跳转物理机会发生什么。会议会保持不变吗?

杰里米说,还有饼干。不用担心这里的负载平衡,但语义比会话更难处理。例如,您必须先发送重定向来编写cookie,然后才能阅读它,而且我从未喜欢过必须添加过期的cookie来删除cookie。由于此数据是您安全性的一部分,因此您可能还需要加密cookie值。

如果使用缓存,数据最有可能最终仍然存在于内存中,例如会话(除非您使用的是SQL会话提供程序)。缓存可能是我的最后选择,因为我们使用Azure,他们的缓存不支持很多很棒的MVC功能。负载均衡器将用户移动到群集中的其他计算机时也会遇到同样的问题,其中可能必须重新缓存数据。

无论哪种方式,您仍然应该为此使用操作过滤器而不是基本的Controller类。

答案 1 :(得分:0)

你在说什么类型的音阶?我们是在谈论一百万用户还是几千个用户?

我的第一个想法是创建一个字典,其中键是登录用户名(假设它是唯一的),并且值是一个关联帐户数组(键或所有数据)。然后我会将字典放入缓存中。每当创建新关联时使其过期。

这种方法存在一些问题。首先,创建新协会的速度有多快?如果它们不断被创建,那么缓存就没有实际意义。你总是去找DB。其次,如果你有数百万用户/协会将所有这些/协会放入缓存可能不实用。

另一种可能性是会话状态服务器,这将仅用于存储关系。

另一种可能性是每次查询数据库,具体取决于数据集的大小。当数据集增长到每次拉实时数据都不实用时,您可以构建一个满足您需求的解决方案。

至于在请求之间保留所选帐户,选项是cookie,url或数据库(可以是用户的字段,即CurrentAccount,这种方法有点像kludge)。

由于您使用的是MVC,我使用URL,路由和自定义路由约束,您可以创建包含该帐户的URL。由于用户必须登录,因此您已经知道用户身份。

示例:http://www.acme.com/{account}/edit/

检查用户是否已登录可以在动作过滤器中处理,也可以在Global.asax中的Application_AuthenticateRequest中处理。身份验证在ASP.NET中实现得相当好。其中很多都是由web.config中的配置值驱动的。

确认身份验证后,帐户重定向可以使用相同的方法进行。或者您可以等待并检查动作过滤器。