DbEntry 开发实践:Wiki 系统(六)

经过 前面一系列的代码编写,我们有了一个可以工作的Wiki系统,现在我们先来给它进行一点儿美化。

  我想象中的布局方式是,顶部是banner,导航栏,编辑、历史等链接,中间是Wiki或者FckEditor,下面是底边栏,显示一些提示信息和版权信息。这可以使用frame、iframe自己编码实现,也可以利用一些工具,我选择使用JQuery和它的插件JQuery Layout。

  在VisualWiki里创建scripts目录,加入jquery和jquery layout,我用的版本是1.2.6。另外,加入jquery-1.2.6-vsdoc.js的话,在Visual Studio里也可以进行JQuery的智能提示。再创建一个styles目录,把BasicStyle.css复制进去,我们还需要多一些css支持,也可以添加到这个css文件中。创建一个images,放入一个banner.jpg文件等等。

  JQuery Layout的写法基本上是定义一些特定class的div,然后把不同的内容,放入不同的div里,然后在script里初始化一下它,就可以了。所以,对于Show或者Edit页面,基本不用修改,只要修改Main.master就可以了,另外,考虑到我们要加入登录功能,我想用master页来进行鉴权工作,分离出一个新的master页也许更好些,Main.master负责鉴权和部分布局(manage部分也需要banner),而Wiki.master负责Wiki的布局,在Main.master里加入对于css和js的链接,并调用jquery layout进行初始化,它还会调用Wiki.master里的resetLayout以完成Wiki页的layout工作:

ExpandedBlockStart.gif 代码
<% @ Master Language = " C# "  Inherits = " Lephone.Web.SmartMasterPageBase "   %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >

< script  runat ="server" >
</ script >

< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head  runat ="server" >
    
< title ></ title >
    
< link  type ="text/css"  href ="styles/BasicStyle.css"  rel ="stylesheet"   />
    
< script  type ="text/javascript"  src ="scripts/jquery-1.2.6.js" ></ script >
    
< script  type ="text/javascript"  src ="scripts/jquery.layout.js" ></ script >
    
< script  type ="text/javascript" >
        
function  resetMainLayout() {
            $(
' form ' ).layout({ slidable:  false , resizable:  false , closable:  false ,
                spacing_open: 
0 , north__size:  52 , center__paneSelector:  " #mainContent "
            });
            
if  (resetLayout)
                resetLayout();
        }
        $(document).ready(
function () { resetMainLayout(); });
        $(window).resize(
function () { resetMainLayout(); });  //  for resize bug with form
     </ script >
    
< asp:ContentPlaceHolder  id ="head"  runat ="server" >
    
</ asp:ContentPlaceHolder >
</ head >
< body >
    
< form  id ="form1"  runat ="server" >
        
< div  class ="ui-layout-north banner" >
        
</ div >
        
        
< div  class ="ui-layout-center" >
        
</ div >

        
< asp:ContentPlaceHolder  id ="ContentPlaceHolder1"  runat ="server" >
        
</ asp:ContentPlaceHolder >
    
</ form >
</ body >
</ html >

  Wiki.master里增加的也基本上是一些div和一个resetLayout函数:

ExpandedBlockStart.gif 代码
<% @ Master Language = " C# "  MasterPageFile = " ~/Main.master "   Inherits = " Lephone.Web.SmartMasterPageBase "   %>

< script  runat ="server" >
    [HttpParameter] public string title;
    [HttpParameter(AllowEmpty 
=   true )] public string path;

    protected 
void  Page_Load(object sender, EventArgs e)
    {
        NavigationBar.Text 
=  CommonHelper.GetNavigationBar(title, path);
        
var  pageName  =  Request.Url.Segments[ 2 ];
        CommonHelper.SetLink(Edit, pageName, 
" Edit.aspx " , title, path);
        CommonHelper.SetLink(History, pageName, 
" History.aspx " , title, path);
    }
</ script >

< asp:Content  ID ="Content1"  ContentPlaceHolderID ="head"  Runat ="Server" >
    
< script  type ="text/javascript" >
        
function  resetLayout() {
            $(
' #mainContent ' ).layout({ slidable:  false , resizable:  false , closable:  false , spacing_open:  0 , north__maxSize:  31 , south__maxSize:  27  });
        }
    
</ script >
    
< asp:ContentPlaceHolder  id ="head"  runat ="server" >
    
</ asp:ContentPlaceHolder >
</ asp:Content >
< asp:Content  ID ="Content2"  ContentPlaceHolderID ="ContentPlaceHolder1"  Runat ="Server" >
< div  id ="mainContent" >
    
< div  class ="ui-layout-north header" >
        
< div  id ="navigator" >
            
< asp:Label  ID ="NavigationBar"  runat ="server"  Text ="Home" ></ asp:Label >
        
</ div >
        
< div  id ="oprator" >
            
< asp:HyperLink  ID ="Edit"  runat ="server" > Edit </ asp:HyperLink >  |
            
< asp:HyperLink  ID ="History"  runat ="server" > History </ asp:HyperLink >
        
</ div >
    
</ div >

    
< div  class ="ui-layout-center body" >
        
< asp:ContentPlaceHolder  id ="ContentPlaceHolder1"  runat ="server" >
        
</ asp:ContentPlaceHolder >
    
</ div >

    
< div  class ="ui-layout-south footer" >
    
< biz:NoticeLabel  ID ="msg"  runat ="server"  SingleLine ="true"   />
    
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    copyright 
&copy  Lephone Studio
    
</ div >
</ div >
</ asp:Content >


  上一张运行截图:



  现在,我们开始设计登录及成员管理功能。DbEntry也支持ASP.Net的MemberShip功能,并且使之可以支持所有DbEntry支持的数据库,不过这里,我们并不使用MemberShip,而是自己设计一个用户表SysUser,其中,password应该是hash的,所以CommonHelper中需要增加一个生成password的函数:

ExpandedBlockStart.gif 代码
private   static   readonly  SHA512 Hash  =  SHA512.Create();

public   static   string  GetHashedPassword( string  password)
{
    var bytes 
=  Hash.ComputeHash(Encoding.UTF8.GetBytes(password));
    var ret 
=  Base32StringCoding.Decode(bytes);
    
return  ret;
}

  SysUser如下:

ExpandedBlockStart.gif 代码
namespace  VisualWiki.Models
{
    
public   enum  UserRole
    {
        Administrator,
        User,
    }

    
public   abstract   class  SysUser : LinqObjectModel < SysUser >
    {
        [Length(
1 50 ), Index(UNIQUE  =   true )]
        
public   abstract   string  Name {  get set ; }

        [Length(
1 128 )]
        
public   abstract   string  Password {  get set ; }

        
public   abstract  UserRole Role {  get set ; }

        
public  SysUser Init( string  name,  string  password, UserRole role)
        {
            Name 
=  name;
            Password 
=  CommonHelper.GetHashedPassword(password);
            Role 
=  role;
            
return   this ;
        }

        
public   static  SysUser GetUserForLogin( string  name,  string  password)
        {
            var pass 
=  CommonHelper.GetHashedPassword(password);
            var u 
=  FindOne(p  =>  p.Name  ==  name);
            
if  (u  !=   null   &&  u.Password  !=  pass)
            {
                
return   null ;
            }
            
return  u;
        }
    }
}

  然后在DataSources里增加SysUserDataSource,同样也不需要有任何代码。然后增加一个使用Main.master的Manage.master页,其中有两个链接,User List和New User。在Main.master的banner上,增加一个Label,显示一下欢迎信息。

  在VisualWiki项目下,增加使用Manage.master的UserList.aspx,向其中添加GridView,SysUserDataSource,并设置GridView的DataSource为SysUserDataSource,添加Role列(这是GridView的bug,不能识别enum列),另外,添加一个HyperLinkField,用来提供一个编辑链接:

< asp:HyperLinkField  Text ="Edit"  DataNavigateUrlFields ="Id"  DataNavigateUrlFormatString ="~/UserEdit.aspx?ID={0}"   />

  UserList.aspx页就开发完成了。UserEdit.aspx页也和 DbEntry.Net主页介绍的编辑页编写流程类似,使用TemplateBuilder可以在几分钟之内完成。这里,我们对于Edit方式,设置Name控件为不可修改,另外,有一个和普通的编辑页面不同的需求,就是Password需要是hash的,所以,在SysUserDataSource 的OnObjectUpdating和OnObjectInserting事件中处理:

ExpandedBlockStart.gif 代码
protected   void  SysUserDataSource1_OnObjectUpdating(SysUser o)
{
    o.Password 
=  CommonHelper.GetHashedPassword(o.Password);
}

protected   void  SysUserDataSource1_OnObjectInserting(SysUser o)
{
    o.Password 
=  CommonHelper.GetHashedPassword(o.Password);
}

  这样,用户管理页面基本开发完毕。我们再增加一个Login页面,这个Login页面不使用任何母板页,在Page_Load里,如果不是PostBack,则进行SignOut操作,而点击SignIn按钮,则调用SysUser.GetUserForLogin验证登录合法性。登录成功,则转向Default.aspx页,而Default.aspx也需要修改一下,根据登录用户的不同类型,重定向到不同的页面:

ExpandedBlockStart.gif 代码
protected   void  Page_Load( object  sender, EventArgs e)
{
    
if  ( this .GetLoginUser().Role  ==  UserRole.Administrator)
    {
        Response.Redirect(
" UserList.aspx " );
    }
    
else
    {
        Response.Redirect(
new  UrlBuilder( " Show.aspx " ).Add(Const.TitleName, Const.HomeName).ToString());
    }
}

  这里,我在WebUIExtends里建立了几个扩展方法,用来协助用户登录操作,比如GetLoginUser、SetLoginUser等等:

public   static  SysUser GetLoginUser( this  Page p)
{
    
return  (SysUser)p.Session[ " LoginUser " ];
}

public   static   void  SetLoginUser( this  Page p, SysUser u)
{
    p.Session[
" LoginUser " =  u;
}

  然后修改Main.master,重载OnInit函数(之所以不是写在Page_Load中,在于ASP.Net在母板页、普通页及控件中奇怪的事件加载顺序),进行用户登录与否的判断,修改Manage.master和Wiki.master,在Page_Load函数里判断登录对象类型,如果类型错误,则返回Login页面,另外,修改web.config中的authentication节,定义登录页面和缺省页面:

< authentication  mode ="Forms" >
  
< forms  name =".ADUAUTH"  loginUrl ="Login.aspx"  defaultUrl ="Default.aspx"  protection ="None" />
</ authentication >

  现在,运行程序,我们会被重导向到Login页面,不过,我们还没有可以用来登录的用户,让我们修改一下Global.asax,以便为我们增加一个管理员:

void  Application_Start( object  sender, EventArgs e)
{
    
if (SysUser.GetCount( null ==   0 )
    {
        SysUser.New.Init(
" tom " " 123 " , UserRole.Administrator).Save();
    }
}

  现在,运行程序,会被带入Login页面,输入tom/123登录,进入管理界面,点击New User链接以增加一个Wiki用户jerry/456,点击Logout退出登录,再使用jerry登录,就可以进入Wiki浏览、编辑界面了。

  这样,用户管理界面也基本开发完毕,本来也以为这应该是这个系列文章的最后,不过,我们还需要处理其它一些细节,所以,提交代码、未完待续……

  目前的代码: VisualWiki6.7z

转载于:https://www.cnblogs.com/lephone/archive/2009/12/06/create_wiki_by_using_dbentry_6.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值