【问题标题】:ASP.net mvc getting the logged username in non-action method returns nullASP.net mvc 在非操作方法中获取记录的用户名返回 null
【发布时间】:2017-02-10 18:29:50
【问题描述】:

我正在尝试为登录用户设置角色,但我无法在从另一个控制器调用的非操作方法中获取登录用户名。我遗漏了一些东西,因为我收到错误:“对象引用未设置为对象的实例”,我理解这是因为登录的用户名在我的 RegisterAsUser() 方法中为空。 我可以调用非操作方法吗?告诉我我做错了什么。提前谢谢!

我的代码:

非动作方法:

    [NonAction]
    [Authorize]
    public void RegisterAsUser()
    {
        //Add User role
        var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
        string role = "User";
        //Create Role User if it does not exist
        if (!roleManager.RoleExists(role))
        {
            var roleResult = roleManager.Create(new IdentityRole(role));
        }

        var store = new UserStore<ApplicationUser>(new ApplicationDbContext());
        var userManager = new UserManager<ApplicationUser>(store);
        string userId = User.Identity.GetUserId();

        if (!Roles.IsUserInRole("Admin"))
        {
            var result = userManager.AddToRole(userId, role);
        }
    }

我在其他控制器中调用 RegisterAsUser() 方法的地方:

public ActionResult Create()
    {
        //set the logged user role to "User"
        IdentityRoleController roleController = new IdentityRoleController();
        roleController.RegisterAsUser();

       ... some other code here...
        return View();
    }

更新:我注意到,如果我用 ActionResult 更改非操作方法并从 url 调用它,它会将角色分配给登录的用户。所以我认为在另一个控制器中用它的非动作方法实例化一个控制器是错误的,但我想知道为什么。

【问题讨论】:

  • 在另一个控制器中实例化一个控制器是邪恶的。不要这样。在您的 Web 项目中创建两个控制器都可以使用的服务方法。
  • 好的,谢谢我会做的
  • @Gert Arnold 可以多解释一下,请问服务方法是什么意思?我用谷歌搜索它,它返回了一些关于网络服务方法的信息。是你的意思?
  • @DanRomulus 他的意思是使用服务接口设计方法。 blogs.msdn.microsoft.com/simonince/2008/08/25/…
  • 我觉得对于我这样的学校项目来说太过分了......

标签: asp.net-mvc entity-framework


【解决方案1】:

还有其他方法可以解决这个问题,例如:

  1. 将 userId 从 Create(父操作)传递给 RegisterAsUser(子操作)和子操作作为 AllowAnonymos(过滤器)。

  2. 使用服务层而不是子操作(这在 OOP 中很重要)。

【讨论】:

    【解决方案2】:

    在其他控制器 B 中实例化控制器 A 时,我面临的问题是,我没有将控制器 A 的 controllerContext 获取到控制器 B 中的实例和其他功能。为了克服这个问题,我使用了这个:

    var controller = DependencyResolver.Current.GetService<ControllerB>();
    controller.ControllerContext = new ControllerContext(this.Request.RequestContext, controller);
    

    ...来自这个帖子:How to call another controller Action From a controller in Mvc [第二个解决方案]

    更新:我找到了更好的解决方案:

    • 创建了另一个文件夹来将我的 RegisterAsUser() 公共方法存储为服务
    • 在 RegisterAsUser() 公共方法中使用它:

    HttpContext.Current.User.Identity.Name 获取当前用户 随着

    using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework;

    • 在创建控制器中实例化:

    var roleService = new IdentityRoleService(); roleService.RegisterAsUser();

    将“用户”角色分配给登录用户

    谢谢大家!

    【讨论】:

      猜你喜欢
      • 2017-01-21
      • 2020-01-12
      • 2012-04-21
      • 1970-01-01
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多