我们在用Asp.Net设计各种Web系统时,经常要设计页面上各个功能的权限控制。比如有权限就提供某个链接入口,那么如何控制页面上的一些功能按钮的权限呢,除了在页面上根据权限设置显示属性外,我在这里提供一个简单有效的方案供参考。如果大家有更好的改进意见,欢迎交流。
首先我们可以在系统中为每个模块页面提供一些功能配置信息,包括功能的名称、代码,这些信息很容易和我们通常用的用户角色、权限挂钩了,接着在模块页面的基类中就可以根据权限创建这些按钮或者工具条了,也就省掉了在页面上控制显示的麻烦了。
那么页面上怎么响应这些事件呢,我们可以让这些功能事件触发时,向页面提供所触发的功能的代码,从而去处理不同的事情了。
您可以在这里下载详细实现Demo。
具体实现的一些局部代码如下:
[ParseChildren( true )]
public abstract class BaseLayoutControl : System.Web.UI.UserControl, System.Web.UI.INamingContainer
{
private System.Web.UI.WebControls.PlaceHolder _cmdBarHolder;
public BaseLayoutControl()
{
}
/**//// <summary>
/// 命令工具条的容器控件。
/// </summary>
public PlaceHolder CmdBarHolder
{
get { return this._cmdBarHolder; }
set { this._cmdBarHolder = value; }
}
protected override void OnInit(EventArgs e)
{
CreateCommandControls();
base.OnInit(e);
}
/**//// <summary>
/// 创建命令按钮。
/// </summary>
protected virtual void CreateCommandControls()
{
if (this.CmdBarHolder != null)
{
InitializeLayout(this.CmdBarHolder);
}
}
/**//// <summary>
/// 初试化页面布局。
/// </summary>
/// <param name="layout"></param>
protected abstract void InitializeLayout(Control holder);
}
[ParseChildren(
true
)]
public class BaseModuleControl : BaseLayoutControl
{
Fields#region Fields
private readonly string ButtonIDFormat = "btnBase{0}";
#endregion
Properties#region Properties
public void SetBaseCmdBtnVisible(string cmdName, bool bVisible)
{
Button cmdBtn = (Button)base.CmdBarHolder.FindControl(
String.Format(this.ButtonIDFormat, cmdName));
if (cmdBtn != null)
{
cmdBtn.Visible = bVisible;
}
}
public void SetBaseCmdBtnOnClickScript(string cmdName, string script)
{
Button cmdBtn = (Button)base.CmdBarHolder.FindControl(
String.Format(this.ButtonIDFormat, cmdName));
if (cmdBtn != null)
{
cmdBtn.Attributes.Add("onclick", script);
}
}
#endregion
Override methods#region Override methods
protected override void CreateCommandControls()
{
if (!Page.Request.IsAuthenticated)
{
Security.AccessDenied();
}
base.CreateCommandControls();
}
protected override void InitializeLayout(Control holder)
{
//
// 根据权限设置用户对该模块的操作权限设置命令按钮的显示和事件。
//
string strModuleCode = this.Page.Request.QueryString["Module"];
if (strModuleCode == null || strModuleCode.Length == 0)
return;
ArrayList accessFunctions = Users.GetCurrentUserModuleAccessPermissions(
Context, strModuleCode);
if (accessFunctions != null)
{
foreach (ModuleFunctionPermission func in accessFunctions)
{
if (func.EnableAccess)
{
holder.Controls.Add(CreateCommandButton(func));
}
}
}
}
private Button CreateCommandButton(ModuleFunctionPermission func)
{
Button cmdButton = new Button();
cmdButton.ID = String.Format(this.ButtonIDFormat, func.FunctionCode);
cmdButton.Text = func.FunctionName;
cmdButton.CausesValidation = false;
cmdButton.CssClass = "button";
cmdButton.CommandName = func.FunctionCode;
cmdButton.Command += new CommandEventHandler(CommandButton_Command);
return cmdButton;
}
#endregion
EventHandler#region EventHandler
private void CommandButton_Command(object sender, CommandEventArgs e)
{
OnCommandButtonClick(e.CommandName);
}
#endregion
Command Messages#region Command Messages
protected virtual void OnCommandButtonClick(string commandName){}
#endregion
}
public class BaseModuleControl : BaseLayoutControl
{
Fields#region Fields
private readonly string ButtonIDFormat = "btnBase{0}";
#endregion
Properties#region Properties
public void SetBaseCmdBtnVisible(string cmdName, bool bVisible)
{
Button cmdBtn = (Button)base.CmdBarHolder.FindControl(
String.Format(this.ButtonIDFormat, cmdName));
if (cmdBtn != null)
{
cmdBtn.Visible = bVisible;
}
}
public void SetBaseCmdBtnOnClickScript(string cmdName, string script)
{
Button cmdBtn = (Button)base.CmdBarHolder.FindControl(
String.Format(this.ButtonIDFormat, cmdName));
if (cmdBtn != null)
{
cmdBtn.Attributes.Add("onclick", script);
}
}
#endregion
Override methods#region Override methods
protected override void CreateCommandControls()
{
if (!Page.Request.IsAuthenticated)
{
Security.AccessDenied();
}
base.CreateCommandControls();
}
protected override void InitializeLayout(Control holder)
{
//
// 根据权限设置用户对该模块的操作权限设置命令按钮的显示和事件。
//
string strModuleCode = this.Page.Request.QueryString["Module"];
if (strModuleCode == null || strModuleCode.Length == 0)
return;
ArrayList accessFunctions = Users.GetCurrentUserModuleAccessPermissions(
Context, strModuleCode);
if (accessFunctions != null)
{
foreach (ModuleFunctionPermission func in accessFunctions)
{
if (func.EnableAccess)
{
holder.Controls.Add(CreateCommandButton(func));
}
}
}
}
private Button CreateCommandButton(ModuleFunctionPermission func)
{
Button cmdButton = new Button();
cmdButton.ID = String.Format(this.ButtonIDFormat, func.FunctionCode);
cmdButton.Text = func.FunctionName;
cmdButton.CausesValidation = false;
cmdButton.CssClass = "button";
cmdButton.CommandName = func.FunctionCode;
cmdButton.Command += new CommandEventHandler(CommandButton_Command);
return cmdButton;
}
#endregion
EventHandler#region EventHandler
private void CommandButton_Command(object sender, CommandEventArgs e)
{
OnCommandButtonClick(e.CommandName);
}
#endregion
Command Messages#region Command Messages
protected virtual void OnCommandButtonClick(string commandName){}
#endregion
}
模块页面只需要继承BaseModuleControl,并且重写OnCommandButtonClick函数,就可以处理相应的功能了。
当然具体页面必须设置功能按钮显示的位置了。