DotNet版的ExtJS单用户Blog系统源码解析

本文介绍了一个结合ExtJS和.NET技术的博客管理系统案例,详细解析了系统搭建过程、源码结构及关键代码实现,包括数据库配置、界面展示、前后端交互等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在讲解源码之前,这里先简单说说系统运行的几个事项。虽然下载的压缩包中已经包含了简单的说明,但有一个重点没有强调,也就是虽然这个系统会在启动的时候自动创建数据库表结构,但他是不能自动创建数据库的,因此在启动之前需要自己手动创建数据库,比如VifirBlog。
数据库的配置是在Web.config文件中,在启动应用程序时,需要修改Web.config文件中的数据库配置,把用户名及密码根据你的情况进行修改,数据库的配置内容如下:
< databaseSettings >
< add key ="db.datasource" value ="(local);IntegratedSecurity=true" />
< add key ="db.user" value ="sa" />
< add key ="db.password" value ="sa" />
< add key ="db.database" value ="vifirblog" />
< add key ="db.generateDdl" value ="true" />
</ databaseSettings >
< appSettings >
db.datasource 表示数据源,默认是SQL Server的,当然你可以选择使用MySQL、Oracle等各种数据源,其中db.user表示用户名,db.password表示密码, db.database表示数据库名,db.generateDdl表示是否让程序启动的时候自动生成表系统所需要的表结构。 db.generateDdl默认为true,第一次运行成功后会自动建表结构,然后请手动修改成false这样下次再启动就不会再建表结构了。
压缩后的文件结构是一个VS项目文件,如下图所示:
如 果你机器上安装了VS2005(SP1)以上的版本,那么理论上应该可以直接双击Vifir.Web.sln这个文件来实现在VS中打开项目(如果装的 VS版本打不开的话,那么你就得好好想办法了,因为本人不是搞.Net的,所以不太清楚为什么,也许其中原因你们比我都专业),如下图所示:
项目打开后,大家可以直接打开Web.config文件,重点看看databaseSettings一节的配置,确认没问题后,可以直接点击上面的运行按钮来运行项目。
启动后即可进行Blog后台管理页面的登录页面,演示系统的用户名及密码均为admin,直接输入后按登录即可进入系统。如下图所示:
进入后可以先进入日志目录管理,程序主区域会出现一个还算漂亮的可编辑表格,可以点击上面的按钮添加日志分类等,并在右边的表格中直接编辑各表格荐的内容。如下图所示:
到这里,这个.Net版的程序就算成功跑起来了。至于系统其它的功能,你就得慢慢体验了,其实也就是三四天做出来的一个小东西,大家可以简单看看即可,用Ext做的更多实用功能(像在线聊天、在线课堂等),可以直接到 http://www.vifir.com/my.html中进行实地体验。下面我们重点对本项目的代码作简单的解析。
由于这里主要演示的是ExtJS与.Net结合应用,因此一个核心就是ExtJS部分,打开manage/Default.aspx中的源代码,可以得到如下的内容:
<% ... @PageLanguage="C#"AutoEventWireup="true"CodeBehind="Default.aspx.cs"Inherits="Vifir.Web.manage.Default" %>
<? xmlversion="1.0"encoding="UTF-8" ?>
<! DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.1//EN""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head >
< meta http-equiv ="content-type" content ="text/html;charset=UTF-8" />
< link rel ="stylesheet" type ="text/css" href ="../plugins/extjs/ext-2.0/resources/css/ext-all.css" />

< style type ="text/css" > ...
a
{...}{text-decoration:none;color:#000033}
.link
{...}{
font-weight
:bold;
padding
:6px00-2px;
line-height
:25px;
}

</ style >
< title > Blog后台管理 </ title >
</ head >
< body style ="font-size:12px" >
< div id ="loading-mask" style ="" ></ div >
< div id ="loading" >
< div style ="text-align:center;padding-top:25%" >< img src ="../images/extanim32.gif" width ="32" height ="32" style ="margin-right:8px;" align ="absmiddle" /> Loading...... </ div >
</ div >
< script type ="text/javascript" src ="../plugins/extjs/ext-2.0/adapter/ext/ext-base.js" ></ script >
< script type ="text/javascript" src ="../plugins/extjs/ext-2.0/ext-all.js" ></ script >
< script type ="text/javascript" src ="manage.js" ></ script >
< script type ="text/javascript" src ="core.js" ></ script >
< script type ="text/javascript" src ="topic.js" ></ script >
< script type ="text/javascript" src ="album.js" ></ script >
</ body >
</ html >
其对应的 Default.aspx.cs 文件内容如下:
namespace Vifir.Web.manage
... {
publicpartialclassDefault:System.Web.UI.Page
...{
protectedvoidPage_Load(objectsender,EventArgse)
...{
if(!UserContext.isAdmin())//如果没有登录
...{
Response.Redirect(
"login.html");//跳转到登录页面
}

}

}

}

在manage/Default.aspx 中,我们没有引入任何特殊的服务器端控件,基本上就是普通的html,注意包含了很多的js文件。其中../plugins/extjs/ext- 2.0/adapter/ext/ext-base.js及../plugins/extjs/ext-2.0/ext-all.js是Ext的库文,而 manage.js、core.js、topic.js、album.js等是我们本系统中编写的ExtJS应用文件,那些艳丽的界面都是直接在这些js 文件中调用ExtJS的组件生成的。对于不熟悉Ext的朋友们来说,我推荐直接通过 《ExtJS实用开发指南》来进行一个系统的学习、并且可以把《指南》作为日常的参考书籍。而对于熟悉Ext并且希望进一步提升的朋友们来说,我建议你直接看 《Wlr单用户Blog系统源码详细开发文档》,该文档中包含了对我们这里用到的manage.js、core.js、topic.js、album.js等文件作了较为详尽的讲解及分析。
由 于这里是一个基于DotNet平台的应用,因此我们重点来看看后台管理部分。后台管理的程序在manage目录中,包含Album.aspx、 AlbumCategory.aspx、Topic.aspx、TopicCategory.aspx、Blog.aspx、Link.aspx、 User.aspx、Comment.aspx等等。经常搞Asp.Net开发的朋友一定会迫不急待的点开这些扩展名为.aspx的文件想看过究竟,看看 这些文件是如何与客户端交付、使用了哪些控件、如何产生JSON、如何访问数据库、SQL语句如何写等。但我想点开后你一定会有所失望了,因为点开这些文 件后你会发现里面几乎什么东西都没有。比如Topic.aspx文件中只包含下面一句大家平时瞟都不会瞟一眼的代码:
<% @ Page Language="C#" AutoEventWireup="true" CodeFile="Topic.aspx.cs" Inherits="manage_Topic" %>
当然,你一定猜到我们一定把处理这些内容的东西都放下面的Topic.aspx.cs文件中了,恭喜你,完全正确!我们重点应该是看aspx下面的C#类文件,比如Topic.aspx.cs,如下图所示:
由 于每一个模块要实现的功能本来就是相似的,使得这些代码都是模板化的,所以你打开其它的Link.aspx.cs、User.aspx.cs、 TopicCategory.aspx.cs都会看到类似的内容,只要搞懂一个,其它的举一反三自然就都懂了。而且在实际开发中,这些代码还真不需要用手 来写(那么用什么呢?当然是用机器人了,简单写一个代码生成工具,替换一下名称就给你搞定了!)。因此,下面我们来重点看看Topic.aspx.cs的 源代码,其全部内容如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Vifir.Model.Service;
using Vifir.Core;
using Vifir.Model.Domain;
using Vifir.Web.Code;
public partial class manage_Topic:BaseAction
... {
privateITopicServiceservice;
privateITopicCategoryServicecategoryService;

publicITopicServiceService
...{
set...{service=value;}
}

publicITopicCategoryServiceCategoryService
...{
set...{categoryService=value;}
}


publicvoidList()
...{
QueryObjectqo
=newQueryObject();
ToPo(qo);
stringcategoryId=Request.Params["categoryId"];
if(categoryId!=null&&!"".Equals(categoryId))
...{
qo.addQuery(
"obj.Category.id",long.Parse(categoryId),"=");
}

IPageListpageList
=service.getTopicBy(qo);
jsonResult
=pageList;
}


publicvoidRemove()
...{
longid=long.Parse(Request.Params["id"]);
service.delTopic(id);
jsonResult
=true;
}


publicvoidSave()
...{
Topicobj
=newTopic();
ToPo(obj);
stringCategoryId=Request.Params["CategoryId"];
if(CategoryId!=null&&!"".Equals(CategoryId))
...{
TopicCategoryc
=this.categoryService.getTopicCategory(long.Parse(CategoryId));
obj.Category
=c;
}

if(!HasError())
service.addTopic(obj);
extFormResult
=true;
}


publicvoidUpdate()
...{
longid=long.Parse(Request.Params["id"]);
Topicobj
=service.getTopic(id);
ToPo(obj);
stringCategoryId=Request.Params["CategoryId"];
if(CategoryId!=null&&!"".Equals(CategoryId))
...{
TopicCategoryc
=this.categoryService.getTopicCategory(long.Parse(CategoryId));
obj.Category
=c;
}

if(!HasError())
service.updateTopic(id,obj);
extFormResult
=true;
}

}

Topic.aspx用来实现日志的添加、修改、删除、分页查询、排序等一系列的功能,我们可以理解为日志管理模块。
前 面的一大堆using我想不用多说,你应该知道就是引入需要用到的包package(或命名空间),其中的System.XX的我想你是见多了,不会有什 么疑问,而Vifir.XX是本系统的域模型、业务逻辑层接口等,另外还包含Vifir的核心类库,你直接像System.XX里面的东西一样在该用的时 候使用是了。(备注:Vifir.Model是本系统的后台业务逻辑,如果你是Vifir的VIP用户,则应该还能够直接下载他的源代码,我也会在后面的 文章中对Vifir.Model中的源码进行具体的分析,Vifir.Core是Vifir提供的一个简单Ajax、Ext支持及企业应用快速开发的开发 库,不是开源项目,但可以免费使用,所以想看他源代码的就只有加入到Vifir团队中才有可能了。当然,看不到也没关系,想想我们虽然没看到 System.XX里面的一句代码,还不是照样屁颠屁颠地用着!)。
下面我们来看看类的声明,代码如下:
class manage_Topic : BaseAction
直接继承自BaseAction,而不是传统的System.Web.UI.PageBaseAction.csCode目录,直接打开可以看到下面的代码:
public abstract class BaseAction:Vifir.Core.Web.AbstractCmdPage
... {
protectednewvoidPage_Load(objectsender,EventArgse)
...{
if(!UserContext.isAdmin())
...{
Response.Redirect(
"login.html");
}

else
...{
base.Page_Load(sender,e);
}

}

}

从 代码中我们可以看出,该类继承自Vifir.Core.Web.AbstractCmdPage,AbstractCmdPage类是从EasyJF开源 团队的EasyJWeb这个开源MVC框架中借鉴来类,用于在Vifir提供用于开发ExtJS的底层开发库,包含了命令处理、JSON数据处理、Ext 表单交互及VO转换成PO等实用方法。如果你对这些内容感兴趣,那么欢迎你直接下载EasyJWeb(官方网址: http://www.easyjf.com/easyjweb/index.html)的源代码来看看即可(其实虽然研究DotNet没多久,但发现. Net的很多东西、特别是设计思想,有不少是得益于Java领域、特别是开源领域的贡献),因此也劝广大的DotNe用户有空时了关注一下Java,他也 许能让你走在前面。
BaseAction中包含了Page_Load方法的公共实现,用来实现用户登 录检查的功能,这里通过调用业务逻辑层的UserContext.isAdmin()来判断是否登录,如果没有登录则把页面导向login.html。如 果登录,则直接调用父类(也就是AbstractCmdPage)中的Page_Load方法来处理用户的请求。
回 到Topic.aspx.cs,继续往下看,我们可以看到service及categoryService字段及属性的声明,在定义Service及 CategoryService属性的时候只设置了set方法,因为该模块中的属性基本上,也不可能给其它程序使用,所以不需要设置get。
下 面来看List方法,该方法的签名为public void List(),是一个普通的方法而已,当用户在地址栏中输入Topic.aspx?cmd=List的时候,会调用该方法中的内容执行。该方法实现的功能 是调用业务逻辑层提供的业务方法getTopicBy,来获得日志信息。getTopicBy方法需要一个参数,即类型为IQueryObject的对 象,该对象中包含了分页及排序的一些相关信息。IQueryObject的一个默认实现的QueryObject,我们直接调用即可。下面是List方法 中的代码及注解:
public void List()
... {
QueryObjectqo
=newQueryObject();//创建一个分页查询对象
ToPo(qo);//把前台传来参数,如分页信息以对象中
stringcategoryId=Request.Params["categoryId"];//得到前台传来的categoryId参数
if(categoryId!=null&&!"".Equals(categoryId))
...{
qo.addQuery(
"obj.Category.id",long.Parse(categoryId),"=");//指定只查询某一个分类中的日志信息
}

IPageListpageList
=service.getTopicBy(qo);//调用业务逻辑层的getTopicBy方法来查询日志,该方法返回的是一个包含了数据分页及内容的IPageList对象。
jsonResult=pageList;//把返回的结构保存到jsonResult中,并作为JSON数据输出。
}

整 个方法的代码如果把处理日志分类的部分去掉的话,就会显得更加简洁了,Web层的东西嘛,就是要追求越简洁越好,最好什么都没有才好维护。不需要专门处理 JSON输出,也不需要根据不同的数据库写一句SQL语句,更不需要计算页码多少、处理排序字段等等,一切交给Vifir提供的类库来处理就OK了。
List方法的代码看完了,我们接下来看看Remove方法,该方法就是简单地根据前台传进来的参数id,调用业务逻辑层的delTopic方法来删除指定日志,代码及注解如下:
public void Remove()
... {
longid=long.Parse(Request.Params["id"]);//获得前台传来参数id并转换成long
service.delTopic(id);//调用业务层的delTopic方法删除指定日志 
extFormResult=true;//指定返回ExtJS表单能识别的数据
}

然后下面是 SaveUpdate 方法的源代码,他们都是用来保存数据, Save 是用来保存新增加的日志,而 Update 用来保存修改的日志。跟前面的方法一样,这些方法都是简单的调用业务逻辑层指定方法来实现日志的保存、修改等功能。下面我们来看看 Save 方法的源码及注解:
public void Save()
... {
Topicobj
=newTopic();//新建一个Topic对象
ToPo(obj);//把表单中传的内容保存到对象obj中,比如表单的title字段值或保存到obj的Title属性中,content或Content字段值会保存到obj的Content属性中,有多少保存多少。
stringCategoryId=Request.Params["CategoryId"];//得到日志分类ID
if(CategoryId!=null&&!"".Equals(CategoryId))
...{
TopicCategoryc
=this.categoryService.getTopicCategory(long.Parse(CategoryId));//调用业务逻辑方法得到指定分类id对应的TopicCategory对象
obj.Category=c;//设置Topic对象的Category值,也就是设置日志分类
}

if(!HasError())//如果没有错误
service.addTopic(obj);//调用业务层的addTopic方法来实现添加日志
extFormResult=true;//设置extFormResult的值为true,返回ExtJS表单Action能识别的JSON数据
}

如 果你一直搞.Net,或者你不知道什么是IOC,那么你一定会疑惑,在上面的代码中ITopicService只是一个接口,也就是service只是一 个接口,而且我们在代码中没给其设置过值,他的实现类具体是什么等。那么请你打开bin目录中的Web.xml这个文件,这是一个Spring.NET的 配置文件,在该配置文件中可以配置各个类及业务组件之间的依赖关注,并给相关类注入依赖的对象。比如配置Topic.aspx.cs类的配置信息如下:
< object type ="manage/Topic.aspx" >
< property name ="Service" ref ="topicService" />
< property name ="CategoryService" ref ="topicCategoryService" />
</ object >
他使得在创建Topic.aspx对应的类实例时,会自动从容器找到名为topicService及topicCategoryService的组件,并注入到Service及CategoryService两个属性中。
关于IOC及Spring.NET,请直接访问Spring.NET的官方网站 www.springframework.net
当然,本示例还引入了一些前沿的后台技术,比如泛型DAO、ORM等。有兴趣的朋友们可以通过vifir.com进一步深入了解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值