在处理完控制器后,保持访问ApplicationUserManager的最佳方法是什么?

时间:2016-02-02 22:26:31

标签: c# asp.net-mvc razor asp.net-identity-2

昨天遇到一个有趣的问题。只有我的身份1的mvc网站我使用IPrincipal扩展方法进行自定义身份验证,这在所有需要它的剃刀视图中都能正常工作。现在使用Identity 2,我需要通过扩展方法访问ApplicationUserManager,因此我被迫从所有视图中传递HttpContext.Current

除了内部剃刀@section部分之外,这种方法很好 - 在调用堆栈之后,看起来这些不会被渲染,直到控制器被处理完毕,这将处理我的数据库和用户管理器等

围绕此限制的最佳方法是什么?我想继续使用部分,因为它们让我轻松地在html的底部注入javascript,但我也想在这些部分中继续使用razor扩展,因为它们是一种非常好的,简单的方法来控制输出到页。

目前我被迫创建一个新的ApplicationUserManagerMyDbContext,将它们填入ViewBag,然后将它们传递给扩展程序,这不是&# 39;理想。

我的扩展方法示例:

public static bool HasPermission(this IPrincipal source, ApplicationUserManager um, MyDbContext db, string controller, string method) {
        if (!source.Identity.IsAuthenticated) {
            return false;
        }

        var roles = um.GetRoles(source.Identity.GetUserId());
        if (roles.Count == 0) {
            return false;
        }

        // Admins have global access
        string role = roles[0];
        if (role.Equals("Admin")) {
            return true;
        }
        // This is fine being un-domained, permissions are global
        PermissionMatrix permission = db.PermissionMatrices.FirstOrDefault(x => x.Controller == controller && x.Action == method && x.RoleName == role);
        return permission != null;
    }

使用地点的示例:

@if (User.HasPermission((ApplicationUserManager)ViewBag.UserManager, (MyDbContext)ViewBag.Database, "Event", "Create")) {
    @Html.ActionLink("Create New", "Create")
}

编辑以使问题本身更清晰:

这是我放入黑客之前的扩展方法 -

public static bool HasPermission(this IPrincipal source, HttpContext context, string controller, string method) {
    var userManager = context.GetOwinContext().Get<ApplicationUserManager>();
    var myDb = context.GetOwinContext().Get<MyDbContext>();

就像我上面说的那样,这有效(从.cshtml页面传递HttpContext.Current),除非调用在剃刀@section内,然后失败,因为这些在控制器之后运行处置完毕,将东西丢弃在OwinContext中。

上面的代码是我现在工作的hacky方式;在我的控制器中,我必须创建一个额外的MyDbContext和一个额外的ApplicationUserManager。

0 个答案:

没有答案