【问题标题】:MVC 5 - retrieving the ApplicationUser objectMVC 5 - 检索 ApplicationUser 对象
【发布时间】:2015-02-07 05:44:43
【问题描述】:

我正在开发一个 MVC 5 互联网应用程序,并且有一个关于在 ApplicationUser 对象中拥有自定义对象的问题。

我在 ApplicationUser 对象中有一个 public virtual Account account 对象,它为我的 MVC 5 应用程序中的对象保存了许多最大计数变量。这是在用户注册帐户时为每个用户设置的。

在创建模型对象之前,我会检查用户是否没有超过模型对象的最大计数。这是在对象的服务类中完成的。

这是用于文件对象的代码示例:

var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
ApplicationUser user = userManager.FindByNameAsync(userName).Result;
int maxFiles = user.account.maxFiles;

我正在为许多具有相似代码的对象使用许多服务类来检索ApplicationUser 对象。

我的问题是:对于每个服务类,不是每次都检索ApplicationUser对象,是否可以在用户登录时存储该对象,然后在创建模型对象之前引用该对象?如果是这样,我可以将这个对象存储在哪里用于上述目的?

另外,检索ApplicationUser 对象时使用了多少内存/带宽?是否使用了最少的内存/带宽,以便在每次创建模型对象之前检索ApplicationUser 对象时无需担心内存/带宽?

提前致谢。

【问题讨论】:

  • 如果该检查是一项非常关键的检查(即,如果它发生更改,您需要在更改发生时反映更改),那么我会说坚持原样,它不是 说实话开销很大。如果不重要,请考虑将其存储在 cookie/会话/缓存中以便更快地查找
  • 我使用 .NET Framework 中的 MemoryCache 类对我的用户查找进行数据缓存。您可以将其配置为只缓存每个用户对象,只要您愿意,它将减少对持久源(数据库)的命中量。

标签: memory asp.net-mvc-5 entity-framework-6 asp.net-identity-2 user-object


【解决方案1】:

这是添加具有登录身份值的声明的典型案例。

当用户登录时,您使用此值添加声明。然后,此声明的值将保留在 cookie 中。并且每次用户回来时都可以使用,这是非常快速的查找,无论如何都会发生 cookie 身份验证。

要将此声明添加到身份,您需要覆盖 ApplicationUserManager 上的 CreateIdentityAsync 方法:

public override async Task<ClaimsIdentity> CreateIdentityAsync(ApplicationUser user, string authenticationType)
{
    var identity = await base.CreateIdentityAsync(user, authenticationType);

    identity.AddClaim(new Claim("MyApplication:maxFiles", user.account.maxFiles));

    return identity;
}

然后要访问它,您可以创建一个扩展方法:

public static int GetMaxFiles(this IPrincipal principal)
{
    if (principal == null)
    {
        throw new ArgumentNullException("principal");
    }

    var claimsPrincipal = principal as ClaimsPrincipal;
    if (claimsPrincipal == null)
    {
        throw new DomainException("User is not authenticated or IPrincipal is not ClaimsPrincipal");
    }

    var claim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == "MyApplication:maxFiles");
    int maxfiles = 0;
    if(int.TryParse(claim.Value, out maxfiles))
    {
        return maxfiles;
    }
    throw new Exception("Claim value is not an integer")
}

在您的应用程序中,您可以将其用作var maxFiles = HttpContext.Current.User.GetMaxFiles()。或者如果是Controller或者View,可以var maxFiles = User.GetMaxFiles()

这是非常快速的查找,不会进入您的数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-12
    • 2015-03-07
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    相关资源
    最近更新 更多