PAYATHON 2026

如何在 DNN Hotcakes Checkout Views 中访问用户角色

支付老李

结论

在 Hotcakes 的 Razor view set 中,可以通过 DNN 的当前用户对象判断用户是否拥有指定角色:

var currentUser = DotNetNuke.Entities.Users.UserController.Instance.GetCurrentUserInfo();
var hasRole = currentUser.IsInRole("x");

取得判断结果后,在 _DisplayPaymentMethods 对应的 case 中,根据 hasRole 决定是否渲染该支付方式。

实现方式

可以先在视图顶部获取当前用户并判断角色,避免在每个 case 中重复查询:

@using DotNetNuke.Entities.Users

@{
    var currentUser = UserController.Instance.GetCurrentUserInfo();

    var canUsePaymentMethod =
        currentUser != null &&
        currentUser.UserID >= 0 &&
        currentUser.IsInRole("x");
}

请将 "x" 替换为 DNN 后台实际配置的角色名称。

然后在现有的 switch 中加入判断:

@switch (payMethod.MethodId)
{
    case "existing-method-id":
        if (canUsePaymentMethod)
        {
            // 保留这里原有的支付方式渲染代码
        }
        break;

    default:
        // 原有的默认处理
        break;
}

如果需要在用户拥有某个角色时隐藏支付方式,将条件取反即可:

case "existing-method-id":
    if (!canUsePaymentMethod)
    {
        // 渲染该支付方式
    }
    break;

直接通过当前请求判断

DNN 通常会将用户角色加载到当前请求的安全主体中,因此也可以使用 ASP.NET 的 IsInRole:

@{
    var canUsePaymentMethod =
        Request.IsAuthenticated &&
        User.IsInRole("x");
}

如果当前 Hotcakes 视图基类没有直接提供 User 或 Request,可以从 HttpContext 获取:

@{
    var principal = System.Web.HttpContext.Current.User;

    var canUsePaymentMethod =
        principal != null &&
        principal.Identity != null &&
        principal.Identity.IsAuthenticated &&
        principal.IsInRole("x");
}

如果还需要访问用户 ID、显示名、邮箱或完整角色数组,使用 UserController.Instance.GetCurrentUserInfo() 更合适。仅判断一个角色时,User.IsInRole(...) 写法更简洁。

查看当前用户的全部角色

调试或判断多个角色时,可以读取 Roles:

@{
    var currentUser =
        DotNetNuke.Entities.Users.UserController.Instance.GetCurrentUserInfo();

    string[] roles = currentUser != null
        ? currentUser.Roles
        : new string[0];

    var canUsePaymentMethod =
        roles.Any(role =>
            string.Equals(
                role,
                "x",
                StringComparison.OrdinalIgnoreCase));
}

使用 Any 前需要引入 LINQ:

@using System.Linq

不过,如果只需判断一个角色,优先使用:

currentUser.IsInRole("x")

这种写法更直观,也不必自行处理角色名称的比较。

版本兼容

部分较旧的 DNN 版本使用静态 API:

var currentUser =
    DotNetNuke.Entities.Users.UserController.GetCurrentUserInfo();

如果 UserController.Instance 无法编译,请根据项目当前引用的 DNN API 改用上述静态调用,不要混用两种写法。

注意事项

在 View 中隐藏支付方式只能控制页面显示,不能代替权限检查。用户仍可能通过修改请求、调用其他结账接口或构造表单数据,提交已经隐藏的支付方式。

因此,除了控制视图输出,还要在服务端处理订单或确认支付方式时再次检查角色:

var currentUser =
    DotNetNuke.Entities.Users.UserController.Instance.GetCurrentUserInfo();

if (!currentUser.IsInRole("x"))
{
    // 拒绝使用仅允许 x 角色使用的支付方式
}

还需注意以下几点:

  • 角色名称必须与 DNN 中配置的实际名称一致。
  • 未登录用户的 UserID 通常小于 0,需要单独处理。
  • 修改 Hotcakes 原始 view set 前,最好先复制并使用自定义主题或自定义视图,以免升级时被覆盖。
  • 用户刚被加入或移出角色后,当前登录会话中的角色信息可能还没有刷新。重新登录通常可以重新加载权限信息。

备注:内容仅供参考。