[翻译]开发自己的web站点管理工具(Website Administration Tool)(1)

简介:
原文地址: http://aspnet.4guysfromrolla.com/articles/052307-1.aspx 
[原文源码下载]


[翻译]开发自己的web站点管理工具(Website Administration Tool)(1)


原文发布日期:2007.05.23
作者: Dan Clem
翻译: webabcd


介绍
基于Forms的验证,再结合ASP.NET 2.0的成员资格和角色管理系统,使得创建和管理用户账户变得相当地简单。 另外,还有一个让人感到非常爽的特性,就是与登录相关的web控件封装了大量的任务,这使得我们不用再像以前ASP那样手写很多代码。 本文用到了ASP.NET 2.0的成员资格和角色管理系统,你可以先参考一下 Examining ASP.NET 2.0's Membership, Roles, and Profiles系列文章。

为了帮助你管理用户、角色和权限设置,ASP.NET 2.0包含了一个  Web Site Administration Tool (WSAT)。 你可以通过Visual Studio 2005的“网站”菜单下的“ASP.NET 配置”选项启动WSAT。 但是,WSAT只允许你管理本地的web站点。 当web站点部署在远程web主机上的时候,WSAT就会受到一些限制。 (WSAT的文件在“%WINDOWS%\Microsoft.NET\Framework\v2.0.50727\ASP.NETWebAdminFiles”文件夹内,你可以在远程部署这个程序。) 

与其把一个已有的WSAT搬到远程主机上,我觉得还是从零开始开发一个自己的WSAT更好一些。 我的版本除了具有WSAT的所有安全相关的特性外,还有一个十分有用的功能,就是“访问规则摘要”,你可以选择任何已有的用户或角色,然后就可以查看他们的目录树型权限视图。 你可以在本文的结尾处下载全部代码,然后就可以快速地将它部署到你的站点上。 本文从整体上讲述了我的自定义WSAT程序的实现,并且详细探讨了用户列表、添加用户和编辑用户的实现方法。在本系列文章的 第二部分(译者注: 中文在这里)中,将会详细地讲解我的自定义WSAT程序中的角色管理和访问规则的管理。 继续往下看,你会知道得更多! 


使用我的自定义web站点管理工具(WSAT)
你可以在本文的结尾处下载我写的WSAT程序的全部代码。 其内包含有虚拟的企业内部网数据,可以用来演示程序的全部功能。 它的全局导航菜单为每一个部门(如IT、marketing、sales等)都提供了一个链接,而每个部门的web页分别存在于不同的文件夹内。 这个演示版使用的provider是SqlMembership,它存储用户信息在程序的App_Data文件夹内的ASPNETDB.MDF数据库。 该数据库是一个Microsoft SQL Server 2005 Express Edition数据库。

按如下的步骤做,你就可以运行这个程序了:
    1、复制所有内容到你机器的硬盘上,而且你的机器上一定要装有Visual Stuido 2005和SQL Server Express。 免费的Visual Web Developer也是可以的。 
    2、打开Visual Studio。 
    3、单击主菜单的“文件”“打开网站”,浏览我的自定义WSAT程序的目录,并打开web站点。 
    4、单击工具栏上的绿色箭头开始调试。 Visual Studio就会启动它的内置web服务器,并在浏览器内显示登录页面。 
    5、登录用户名为“Dan Clem”,密码“dan”。 Dan Clem是系统管理员。 你也可以用接下来的任何非管理员用户登录。 “Edward Eel”,“Frankin Forester”,“Gordy Gordon”,“Harold Houdini”,或者“Ike Iverson”。 每一个用户的密码就是其first name的小写。 
    6、在全局导航菜单上单击“Admin”链接,你就可以看到程序的最主要的部分。 导航菜单上的其它链接分别指向我虚拟的企业内部网的各个部门的目录。 你可以在“访问规则管理”页和“访问规则摘要”页设置每个目录的访问权限。

如果你要把这个自定义的WSAT程序移植到你的已存在的并且使用了Memebership和Roles的程序中去的话,那么就需要完成如下步骤:
    1、复制admin文件夹到你的ASP.NET程序的根目录下。 (在我的程序里,我把admin文件夹放到了web站点的根目录下,不过如果将其放到ASP.NET程序下的某个子文件夹内也是可以正常工作的) 
    2、复制Alphalinks用户控件(alphalinks.ascx)到你web站点的一个合适的目录内,然后修改users.aspx页的@Register指令,使其匹配新的地址。 (关于用户控件是如何工作的更详细的说明,可以参看 An Extensive Examination of User Controls) 
    3、复制i目录下的图片文件到你程序的一个合适的文件夹内,然后修改access_rules.aspx页和access_rule_summary.aspx页内的图片链接地址。 
    4、在你的程序根目录下的web.config文件内的system.web节点下注册如下命名空间。 它们是程序里的一些web页需要用到的命名空间,如使用DataTable类和DirectoryInfo类的时候。 
<pages>  
     <namespaces>  
            <add namespace="System.Data" />  
            <add namespace="System.IO"/>  
     </namespaces>  
</pages>
5、要修改导航菜单样式的话,应该在母版页中修改。 (我既用到了ASP.NET 2.0中的方法,又用到了传统的ASP方法。例如,全局导航菜单我写到了母版页里,Admin下的导航菜单我写到了一个文件里,需要用到它的页会把它include进来) 
    6、注意,admin文件夹下有两个子文件夹: access和activity。 我的WSAT程序的全部功能都包含在access文件夹内。 增加activity文件夹的作用是,我想在这里增加日志功能。 
    7、我们需要给admin文件夹增加权限配置,以使允许的角色或用户才能使用这个功能,后面我们会详细说到。

如果你已经下载了这个程序,并且已经安装了,那么通过本文接下来的内容,你就会了解如何添加用户、编辑用户,以及如何使用用户列表。 本系列文章的第二部分(译者注:中文在这里)主要用于讲解角色管理和访问规则的实现。 本文和下一篇文章所带来的东东,可以作为你管理权限的一个非常好的工具。


管理用户帐号
官方的ASP.NET 2.0 WSAT程序提供了一套用于管理web站点的用户、角色和访问规则的页面。 而在我开发的这个自定义WSAT程序中,除了保留所有原WSAT的核心功能外, 还增加了一个非常拥有的功能,即“访问规则摘要”,它可以非常方便地查看到每个角色或用户对站点内每个目录和文件的访问权限。 我开发了一套用户列表页面,它具有我们平时常用的功能。 具体如下: 
    ·按用户名搜索用户
    ·按角色名搜索用户
    ·可用用户
    ·在线用户
    ·被锁定的用户

下面的截屏就展示了这些功能。 这个GridView用于显示web站点的用户及其详细信息。 GridView上面的一排连接允许你按用户搜索,或者角色搜索,又或者仅仅查找可用用户、在线用户或被锁定的用户。 而“User Name filter”可以让你通过用户名的首字母进行搜索。 
 
按用户名搜索用户
通过用户名查找用户就是靠下面两行代码实现的:
Users.DataSource = Membership.GetAllUsers();  
Users.DataBind();
 
.NET框架内的Membership类有一个用来检索所有用户信息的方法,就是GetAllUsers()方法,它会返回站点的所有用户。

我想在WSAT程序里增加一个按用户名首字母搜索用户的功能, 所以我决定创建一个ASP.NET用户控件,稍后我会用到它。 因为我是刚刚才学的如何创建ASP.NET用户控件,所以完成它比我计划的花了更多的时间,但从中我也学到了很多东西,现在我就来和大家分享一下。 我把这个控件称作“Alphalinks”,一共开发了两个版本。 第一个版中本我用的是传统的ASP的方法,也就是基于QueryString的导航。 控件会把首字母以QueryString的形式加到链接上,就像这样:&letter=X。

之后的第二个版本里,我就跟基于QueryString的导航方式说再见了,而是使用一个有合适的postback的用户控件做导航。 而且,我很快就意识到了这样使用的好处。 也就是我们可以通过属性的方式访问控件的值,这要优于使用传统的ASP方式的Request.QueryString。 详细点说,就是我给Alphalinks控件增加了一个Letter属性,它可以返回被选择的字母。 增加了这个属性后,这个控件就可以像下面这样使用了: 
Users.DataSource = Membership.FindUsersByName(Alphalinks.Letter + "%");
 
 
按角色名搜索用户
按角色名搜索用户的功能是使用一个GridView来展现的,它会显示出你指定的角色下的所有用户。 在这里我使用了一个DropDownList来代替Alphalinks控件,这个DropDownList会列出系统内的所有角色。 DropDownList所绑定的数据就是用Roles类的GetAllRoles()方法所取得的数据,如下所示: 
UserRoles.DataSource = Roles.GetAllRoles();  
UserRoles.DataBind();
 
接下来的逻辑有些复杂,因为Membership和Roles都没有给我们提供通过角色返回所有用户的详细信息的方法。 虽然Roles类有一个GetUserInRole(roleName)的方法,但是它返回的只是你指定的角色下的所有用户的用户名,而没有用户的如email、状态、最后登录日期之类的详细信息。 没有现成的方法,我就自己写一些代码来返回指定角色下的所有用户的详细信息。 我先把指定角色下的用户名全部取出,然后再根据用户名把相应的用户的详细信息添加到一个集合中。 
// 获取所有用户 
MembershipUserCollection allUsers = Membership.GetAllUsers();  
MembershipUserCollection filteredUsers =   new  MembershipUserCollection();  
 
if  (UserRoles.SelectedIndex > 0)  
{  
       // 得到指定角色下的用户名 
       string[] usersInRole = Roles.GetUsersInRole(UserRoles.SelectedValue);  
        
       // 将指定角色下的所有用户的详细信息添加到filteredUsers 
       foreach  (MembershipUser user   in  allUsers)  
     {  
             foreach  ( string  userInRole   in  usersInRole)  
            {  
                   if  (userInRole == user.UserName)  
                 {  
                        filteredUsers.Add(user);  
                         break;    
                 }  
            }  
     }  
}  
else  
{  
     filteredUsers = allUsers;  
}  
 
// 绑定用户信息到GridView 
Users.DataSource = filteredUsers;  
Users.DataBind();
 
最后的3个页(可用用户、在线用户、被锁定的用户)都比较简单。 它们都是先通过Membership.GetAllUsers()方法来得到所有用户,然后再根据MembershipUser对象的某个属性来判断是否要把该用户添加到一个MembershipUserCollection集合里。 最后再把这个集合绑定到GridView,并显示在页面上。 注意:可用用户对应的是MembershipUser类的IsApproved属性,在线用户对应的是IsOnline属性,被锁定用户对应的是IsLockedOut属性。


另一种筛选用户的方法
如果要筛选用户,一般我们都会使用上面所述的逻辑。 首先通过Membership.GetAllUsers()获得所有用户,然后再根据条件筛选,把需要的用户添加到一个集合里。 但是,如果有大量用户的话,就不适合用这个方法了。 如果你的系统可能用数百个以上的用户,那么就应该考虑放弃用这个方法,而是使用更高效的技术了。

例如,如果你使用的是SqlMembershipProvider的话,那么就应该在在数据库中添加一个存储过程以返回筛选后的用户信息,存储过程要做的工作就是关联aspnet_Users、aspnet_Membership、aspnet_Roles和aspnet_UsersInRoles,然后按条件筛选数据。 同样地,你还应该使用自定义分页逻辑来高效地返回指定的数据给GridView(参看Custom Paging in ASP.NET 2.0 with SQL Server 2005)。
 

创建新的用户
通过Membership类的CreateUser()方法可以很方便地新建用户。 我的这个WSAT程序里包含一个“新建用户”页,其内有一个CheckBoxList控件,用于让你选择用户所属的角色身份。 

在设计Membership系统的时候,微软决定只封装用户的核心信息,如用户名、密码和最后登录日期之类的。 如果我们需要在程序里增加用户的其他信息的话,如性别、地址和生日之类的,那么我们可以使用Profile系统或者开发自己的一套管理用户其他信息的逻辑。关于ASP.NET 2.0的Profile系统可以参看Profiles in ASP.NET 2.0。要在自定义表里保存用户的其他信息的话可以参看Customizing the CreateUserWizard Control

下面就是“新建用户”页的截屏:
 
实现新建用户功能的代码非常简单: 下面例子中的第一行用于添加用户;第二行用于添加备注(因为CreateUser这个方法里没有“备注”这个参数)。 成功添加用户之后,通过foreach循环CheckBoxList的各项,然后再给新建的用户添加相关的角色。 
protected   void  AddUser()  
{  
       // 添加用户 
     MembershipUser newUser = Membership.CreateUser(username.Text, password.Text, email.Text);  
     newUser.Comment = comment.Text;  
     Membership.UpdateUser(newUser);  
        
       // 添加角色 
       foreach  (ListItem rolebox   in  UserRoles.Items)  
     {  
             if  (rolebox.Selected)  
            {  
                 Roles.AddUserToRole(username.Text, rolebox.Text);  
            }  
     }  
}
 
编辑已有用户
“编辑用户”页和“新建用户”页差不多,你可以通过用户信息列表页的链接访问到“编辑用户”页。 在这个页中我使用CheckBoxList来编辑用户所属角色,用DetailsView来显示用户的信息。 因为CheckBoxList与DetailsView是两个控件,所以我必须手动地设置复选框的状态,以使CheckBoxList和DetailsView保持信息上的同步。
private   void  Page_PreRender()  
{  
       // 让CheckBoxList绑定所有角色 
     UserRoles.DataSource = Roles.GetAllRoles();  
     UserRoles.DataBind();  
 
       // 如果不是编辑状态,则所有复选框都应该是不可用的状态 
       if  (UserInfo.CurrentMode != DetailsViewMode.Edit)  
     {  
             foreach  (ListItem checkbox   in  UserRoles.Items)  
            {  
                 checkbox.Enabled =   false;  
            }  
     }  
        
       // 如果用户属于某个角色,则勾选相应的复选框 
       string[] userRoles = Roles.GetRolesForUser(username);  
       foreach  ( string  role   in  userRoles)  
     {  
            ListItem checkbox = UserRoles.Items.FindByValue(role);  
            checkbox.Selected =   true;  
     }  
}
 
另外,我还写了一些用于从角色中添加或移除用户的代码,这是必需的。 这段代码将在DetailsView的OnItemUpdating事件中被调用。 
private   void  UpdateUserRoles()  
{  
       foreach  (ListItem rolebox   in  UserRoles.Items)  
     {  
             if  (rolebox.Selected)  
            {  
                   if  (!Roles.IsUserInRole(username, rolebox.Text))  
                 {  
                        Roles.AddUserToRole(username, rolebox.Text);  
                 }  
            }  
             else  
            {  
                   if  (Roles.IsUserInRole(username, rolebox.Text))  
                 {  
                        Roles.RemoveUserFromRole(username, rolebox.Text);  
                 }  
            }  
     }  
}
 
 
结论
本文从整体上讲述了我的自定义WSAT程序的实现(本文结尾处你可以下载到这个程序),并且详细探讨了用户列表、添加用户和编辑用户的实现方法。 关于角色管理和访问规则的管理请参看本系列文章的第二部分(译者注:中文在这里)。


到这里本文结束。 祝编程愉快!
 



     本文转自webabcd 51CTO博客,原文链接:http://blog.51cto.com/webabcd/345070 ,如需转载请自行联系原作者

相关文章
|
3天前
|
Web App开发 IDE 测试技术
Selenium:强大的 Web 自动化测试工具
Selenium 是一款强大的 Web 自动化测试工具,包括 Selenium IDE、WebDriver 和 Grid 三大组件,支持多种编程语言和跨平台操作。它能有效提高测试效率,解决跨浏览器兼容性问题,进行性能测试和数据驱动测试,尽管存在学习曲线较陡、不稳定等缺点,但其优势明显,是自动化测试领域的首选工具。
59 16
Selenium:强大的 Web 自动化测试工具
|
11天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
27 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
7天前
|
前端开发 安全 JavaScript
2025年,Web3开发学习路线全指南
本文提供了一条针对Dapp应用开发的学习路线,涵盖了Web3领域的重要技术栈,如区块链基础、以太坊技术、Solidity编程、智能合约开发及安全、web3.js和ethers.js库的使用、Truffle框架等。文章首先分析了国内区块链企业的技术需求,随后详细介绍了每个技术点的学习资源和方法,旨在帮助初学者系统地掌握Dapp开发所需的知识和技能。
2025年,Web3开发学习路线全指南
|
14天前
|
存储 前端开发 JavaScript
如何在项目中高效地进行 Web 组件化开发
高效地进行 Web 组件化开发需要从多个方面入手,通过明确目标、合理规划、规范开发、加强测试等一系列措施,实现组件的高效管理和利用,从而提高项目的整体开发效率和质量,为用户提供更好的体验。
24 7
|
18天前
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
|
18天前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
33 2
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
146 3
|
1月前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
154 45
|
1月前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
44 1
|
1月前
|
XML 安全 PHP
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。