您的位置:首页 > 其它

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

2009-12-07 23:46 295 查看
流水帐记到现在,系统基本完成,不过还有几点需要解决。

  首先,我们来添加一个“记住我”的功能。当用户登录的时候,如果选择了“Remember Me”,那么就同时把用户名密码等信息保存到用户的cookie中,用户访问时,先检测cookie,如果cookie中有保存的信息,则验证此信息,如果验证通过,则建立相应的session,否则导向Login页面。

  先在SysUser中建立序列化和反序列化的两个函数:

代码protected void Page_Load(object sender, EventArgs e)
{
ErrMsg.Visible = false;
if (!IsPostBack)
{
SysUser u = this.GetLoginUser();
if (u != null)
{
this.SetLoginUser(null);
}
FormsAuthentication.SignOut();
var luc = Request.Cookies[Const.LoginCookie];
if (luc != null)
{
luc.Expires = DateTime.Now.AddDays(-1);
luc.Value = "";
Response.Cookies.Set(luc);
}
}
}

protected void SignIn_Click(object sender, EventArgs e)
{
ProcessLogin(UserName.Text, Password.Text);
}

private void ProcessLogin(string name, string password)
{
SysUser u = SysUser.GetUserForLogin(name, password);
if (u != null)
{
this.SetLoginUser(u);
if (RememberMe.Checked)
{
var cookie = new HttpCookie(Const.LoginCookie, SysUser.SerializeToString(u.Name, password)) { Expires = DateTime.Now.AddDays(30) };
Response.Cookies.Add(cookie);
}
var url = Request[Const.BackToUrl];
if(!string.IsNullOrEmpty(url))
{
Response.Redirect(url);
}
else
{
Response.Redirect("Default.aspx");
}
}
else
{
ErrMsg.Text = "User name or password error!";
ErrMsg.Visible = true;
}
}
  运行程序,验证如果选择了Remember Me,则再次直接访问页面,不再需要登录,而且,Welcome信息显示名称正确;如果点击了Logout,再次运行程序,则仍然需要登录。现在,这个功能开发完毕。

  第二个要完成的功能,是Wiki和用户关联。既然我们现在有登录用户了,自然可以记录下究竟是谁修改了哪个Wiki页。

  修改Article和ArticleHistory,增加User:

[BelongsTo]
public abstract SysUser User { get; set; }
  然后修改它们两个的Init函数和SaveArticle函数,增加对于user的支持,编译程序,将以前只提供两个参数的Init和SaveArticle函数调用,都改成也提供user的形式。现在我们实际上已经修改了数据库表结构,所以删除App_Data目录下的wiki.db文件,再次运行程序,创建用户、编辑文章,还和以前一样的操作,不过,我们已经记录了编辑者,只是还没有显示出来而已。

  在History.aspx里增加user列:

<asp:TemplateField HeaderText="User">
<ItemTemplate><%# ((ArticleHistory)(Container.DataItem)).User.Name %></ItemTemplate>
</asp:TemplateField>
  在Show.aspx里增加一个tip变量,一个msg变量,这个msg变量,标记为InMaster,以便我们访问母板页里的msg控件:

[InMaster] public Lephone.Web.Common.NoticeLabel msg;
private string tip;
  然后在Page_Load里对tip进行赋值,再override OnPreRender函数,添加这个tip(之所以需要这样,而不是直接在Page_Load里操作,也是因为asp.net奇怪的事件加载顺序):

protected override void OnPreRender(EventArgs e)
{
if(!string.IsNullOrEmpty(tip))
{
msg.AddTip(tip);
}
}
  现在,运行程序,Show页面底边将会显示编辑者的名字和编辑的时间,History页面也会显示编辑者的名字了。

  最后,我们再考虑一下性能。对于Show页面而言,问题不大,不过,History页面,并不显示Content,却需要加载它,是有些浪费的,所以,我们标记ArticleHistory的Content为延迟加载:

[LazyLoad]
public abstract string Content { get; set; }
  另外,History里显示用户名,Show页面显示用户名,都需要访问数据库,History更是多次访问数据库读取sys_users表,只为得到用户名,对于这一点,我们给它加个缓存,在web.config里添加:

<add key="CacheEnabled" value="true" />
  在SysUser上标记可以被缓存:

[Cacheable]
public abstract class SysUser : LinqObjectModel<SysUser>
  为了运行时可以跟踪生成的SQL语句,也为了验证一下我们缓存的效果,修改web.config中的log设置,将它设置为将生成的sql写入数据库:

<add key="SqlLogRecorder" value="Lephone.Data.Logging.DatabaseLogRecorder, Lephone.Data" />
  分别以打开和关闭缓存的方式访问相同的网页,之后检查数据库lephone_logs表里的SQL语句,验证有缓存时生成SQL数量较少。另外,ArticleHistory相关的Select语句在History页面不会有Content在内。

  好的,这个VisualWiki系列文章到这里算是全部结束了,虽然这个Wiki系统,还有一些功能有待完善,比如历史比对功能等,不过,它已经是一个可以运行,并且用起来也颇顺手的Wiki了,作为我前一个公司的内部Wiki系统,它一直运行,而且表现不错。最终代码:VisualWiki7.7z

  全文完。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: