使用LINQ过滤ASP.NET应用程序中的用户角色和权限

在开发Web应用程序时,经常需要处理用户角色和权限。本文将介绍如何使用LINQ(Language Integrated Query)在ASP.NET应用程序中过滤用户角色和权限数据,以提高代码的效率和可读性。

假设有一个Web页面,用于显示应用程序中的用户角色及其权限。

有些权限(如“允许访问站点/用户/角色维护”)没有列出的角色被批准。对于这些角色来说,这些权限是无关紧要的。在页面上显示它们只会混淆用户,并引发支持问题。

目标是过滤掉至少有一个角色未批准的行。这样,就可以确保只显示与用户角色相关的权限,从而避免混淆。

数据是通过ASP.NETGridView控件显示的,该控件绑定到了一个DataSet对象。为了过滤掉不需要的行,决定在设置GridView的DataSource属性并调用其DataBind方法之前,先过滤DataSet。

GridView的第一列将包含权限描述的字符串,每个后续列将包含一个布尔值,指定该角色是否被批准该权限。从图中不容易看出的是,角色的数量是由数据库驱动的,而不是静态的。如果向应用程序添加另一个角色,这里将添加另一个列,不希望修改代码以适应额外的角色。

以下是调用过滤DataSet的方法的代码:

C# DataSet ds = GetMyRoleData(); FilterRows(ds); RoleComparisonView.DataSource = ds; RoleComparisonView.DataBind();

GetMyRoleData是一个虚拟方法,用于获取所需的数据,这里不展示。然后调用FilterRows方法,该方法将删除所有没有角色批准该行权限的DataSet中的行。然后设置GridView的DataSource属性并调用DataBind方法。到目前为止,没有什么特别的。

接下来是实际过滤不需要的行的方法。通过枚举每一行,然后枚举行的每一列,这是非常简单的。如果每一列都设置为false,则删除该行。或者,如果任何列是true,则不删除该行。后者将更有效,因为可以在第一个列有一个true值时停止检查。

但是,与其枚举每一列并检查其值,不如使用LINQ使代码更简单。为什么不使用Any运算符呢?如果行的项目数组中的任何元素是true,那么就不希望删除该行。或者,可以使用All运算符,并确保它们都设置为false,但这将效率更低,需要检查每个项目。使用Any运算符而不是All运算符允许代码在项目是true时停止。

还有一个最后的复杂性,那就是每个DataRow的第一列是一个字符串,用于权限描述,而不是布尔值,用于角色。这可以通过OfType运算符轻松克服。只需在项目数组ItemArray上调用OfType运算符,并指定只返回布尔值类型的元素。就是这么简单。以下是代码:

private void FilterRows(DataSet ds) { bool someRoleHasPermission; foreach (DataRow dr in ds.Tables[0].Rows) { someRoleHasPermission = dr.ItemArray.OfType().Any(b => b == true); if (!someRoleHasPermission) { dr.Delete(); } } }

枚举DataTable的Rows集合中的每个DataRow。然后,调用行的ItemArray的OfType运算符,以返回布尔值类型的项目。最后,调用Any运算符,并提供一个lambda表达式,如果任何项目设置为true,则返回true。非常简单。然后,如果LINQ查询返回false,调用DataRow的Delete方法。就这样,权限已经被过滤了。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485