在开发SunBlog模块的过程, 我发现每次都需要定制模块的编辑权限(Edit Module)给Blog Owner, 如此一来比较麻烦, 再说这样导致权限分配极其模糊, 其实我只是需要赋予Blog Owner管理博客的权限而已, 并非编辑模块的权限, 按照之前的做法, 如果使用该Blog Owner登录进来时页面顶部会出现类似下图的控制区域的标签, 可实际上该用户并没有编辑页面的任何权限, 这无疑是冗余的呈现:

对此解决的方案就是需要我们重新定义一种介于View和Edit之间的权限, 让其履行相应的职责, UDT, Feedback和Forum模块就是典型的例子。一般的做法是我们在更新模块时添加我们所需要的自定义权限, 然后再重新分配权限即可, 比如我们现在需要的是管理博客这一权限, 其步骤如下:
1) 模块实现IUpgradeable接口, 本例子将创建一个类InterfaceController负责接口的实现, 基本代码如下:
public class InterfaceController:IUpgradeable
{
public string UpgradeModule(string Version)
{
string message = string.Empty;
CustomUpgrade update = new CustomUpgrade();
switch (Version)
{
case "01.00.02":
// first version as DotNetNuke sub project
message = message + " In Custom Upgrade Version " + Version + " - ";
message += update.InitModulePermission();
break;
}
return message;
}
}
你会发现其实代码蛮简单, 就是在实现接口的方法UpgradeModule里边执行添加权限的逻辑.
2) 实现我们定制的添加权限方法, 这将由类CustomUpgrade来负责, 在此我们将创建方法InitModulePermission来封装添加权限的逻辑, 代码如下:
public string InitModulePermission()
{
try
{
bool canManage = false;
// Step 1: get all Permissions which have the PERMISSION_CODE
PermissionController permCtl = new PermissionController();
ArrayList arr = permCtl.GetPermissionByCodeAndKey(ConfigManager.PERMISSION_CODE, "");
// Step 2: get the related modules which you want to bind
int moduleDefId;
DesktopModuleController desktopMod = new DesktopModuleController();
DesktopModuleInfo desktopInfo = desktopMod.GetDesktopModuleByModuleName("SunBlog");
ModuleDefinitionController modDef = new ModuleDefinitionController();
ModuleDefinitionInfo modDefInfo = modDef.GetModuleDefinitionByName(desktopInfo.DesktopModuleID, "SunBlog_Nav");
moduleDefId = modDefInfo.ModuleDefID;
// step 3: check whether exist the permission
foreach (PermissionInfo p in arr)
{
if (p.PermissionKey == ConfigManager.MANAGE_PERMISSION & p.ModuleDefID == moduleDefId) canManage = true;
}
try
{
if (!canManage)
{
// step 4: Add the new permission information
PermissionInfo pi = new PermissionInfo();
pi.ModuleDefID = modDefInfo.ModuleDefID;
pi.PermissionCode = ConfigManager.PERMISSION_CODE;
pi.PermissionKey = ConfigManager.MANAGE_PERMISSION;
pi.PermissionName = "Manage SunBlog";
permCtl.AddPermission(pi);
}
}
catch
{}
}
catch (Exception ex)
{
Exceptions.LogException(ex);
}
return "Upgrade SunBlog finished";
}
如果你仔细研读上边的代码, 逻辑极为清晰, 首先需要判断是否存在具有同样代码号的权限, 同时需要确认你所添加的模块是否已绑定这一权限, 是则忽略添加, 反之则构建我们需要添加的权限对象并执行添加操作. 这里有一点需要注意的是权限名称的本地化, 比如现在该权限名称设置为"Manage SunBlog”(请细读以上代码), 那你只要在App_LocalResources新建共享本地化文件SharedResources.resx(中文则应该为SharedResources.zh-CN.resx), 然后在该资源文件里新增一组键值对属性xx_yourpermissionName.Permission(本例子则为Manage SunBlog.Permission –> 管理博客).
3) 重新打包模块并安装, 注意需要在模块定义文件(*.dnn)version标注对应代码中的版本号(也就是
01.00.02), 使两者保持一致, 该例子需要更新的版本号为01.00.02. 如果升级成功则当你打开该模块的设置编辑页时将发现自定义的权限, 如图:

4) 模块中如何使用新添加的权限呢?我们可以定义一个辅助类来获取这一新添加的权限属性, 假设这一个类为ModuleSecurity, 其中包含CanManage这一权限属性, 详细代码如下:
using DotNetNuke.Security.Permissions;
using DotNetNuke.Entities.Modules;
namespace DnnSun.Modules.Utility
{
public class ModuleSecurity
{
private bool _ManagePermission;
public ModuleSecurity(ModuleInfo modInfo)
{
string code = ConfigManager.MANAGE_PERMISSION;
_ManagePermission = ModulePermissionController.HasModulePermission(modInfo.ModulePermissions, code);
}
public bool CanManage
{
get { return _ManagePermission; }
}
}
}
到此我们就可以直接在模块代码中如此判断当前用户是否具有这一个权限:
ModuleSecurity modSecurity = new ModuleSecurity(this.ModuleConfiguration);
if ( modSecurity.CanManage)
{
// maybe you will throw a exeception or show a message
}
else
{
// do anything what the current user can do
}
源代码下载:
UtilityModule_SourceCode.zip
参考链接:
Custom Module Permissions. Enhance your modules!