因为帅烦 发表于 2006-12-28 23:16:32

[原创]新站发布测试版本 - GZBBS [源代码+数据库] ■■■■■■■■■

只是发布测试版本而已,源代码全部开放,介绍原来发过了,不多说了,只要实现了三层的简单的思想,还没有什么面向对象的东西在里面。等写完毕业论文继续更新功能。大家共同学习,呵呵。程序简陋请勿笑。

安装方法。
    打开SQL Server 2000数据库,新建一个数据库04net,然后选择还原数据库,选择从设备,把网站文件夹根目录的“04net”还原到04net既可。
   拷贝论坛文件夹到IIS目录,把文件夹的安全选项添加IUSR(iis来宾账户)的读取权限。在IIS里面设置ASP.NET选项设置ASP.NET版本为2.0,主目录设置为论坛所在的目录。

建议使用
   操作系统: Windows 2003 Server
      IIS:6.0版本
      数据库:Microsoft SQL Server 2000
      .Net平台:Microsoft .NET Framework v2.0

如果装不上去可以更帖,因为现在功能没做完,所以就不多介绍了,希望对asp.net新手有帮助。

[ 本帖最后由 因为帅烦 于 2006-12-28 23:18 编辑 ]

因为帅烦 发表于 2006-12-28 23:21:39

部分功能介绍+++++++++++++++++++++++++
注册和登陆功能实现方法概述

使用技术:AJAX、JS、三层结构。
  注册和登陆页面使用技术和方法基本上一致,通过编写的JavaScript脚本实现了很强的互交功能,包括提示用户注册信息和配合Ajax无刷新服务器回传检测用户注册所使用的用户名字是否已经存在,以及实现用户登陆时候检测用户未输入密码时候验证用户名是否正确。所有和数据库的操作和验证逻辑都使用三层结构思想来实现的。

页面功能的实现
  注册页面用分二部分,使用二个Panel实现,当打开注册页面时出现第一个Panel显示注册条款,当点击同意后出现第二个Panel显示输入用户资料。

  在输入用户名字时候,当用户输入的用户名发生改变时候会触发在JavaScript/ register.js 文件里面的一个JavaScript事件Name_change(),由于JavaScript脚本不能实现和Asp.Net服务端进行通讯,所以会使用Ajax向Ajax.ashx文件发送一个XMLHTTP请求,由于Ajax.ashx能够实现和服务端的互交,Ajax.ashx的Chk_UserName方法根据传进来的参数执行一个业务逻辑层UserBLL.cs的Select_UserName方法,该方法执行数据层UserDAL.xsd的Select_Count_UserName方法通过返回一个boll值,反馈给Ajax.ashx用户所输入的用户名是否存在,然后再返回到register.js,通过register.js的Name_change_onReadyStateChange向页面写如一个反馈信息以提示用户名字是否存在。

  以上便是当用户输入要注册的用户名字时候,自动执行服务器回传,向数据库查询此用户名是否已存在,然后通过JavaScript在页面中提示相应提示信息的一个功能。整个流程是:用户输入→JavaScript→Ajax→业务逻辑层→数据层→业务逻辑层→Ajax→JavaScript→页面提示。这一切看起来好像很复杂,但是却又是缺一不可。虽然实现起来的确有点麻烦,但是这一切都是在用户无需要任何操作的情况下发生的。当用户输入完用户名后立即提示该用户名字是否可以注册,不需要点击“检查用户名是否已存在”之类的按钮或者在点击注册后才提示,没有任何刷新或者任何操作,实际上一系列验证只需要在用户输入用户名字后立即显示出结果,对于提高网站互交功能、给用户更好的注册体验是非常有帮助的。

  用户登陆的实现方法也是和注册功能是一样的,使用的方法、功能和流程也基本一致,只不过在数据库操作上面不同而已。

首页功能实现

首页功能实现方法概述
  使用技术:Repeater嵌套Repeater、ObjectDataSource、.Net2.0三层结构实现。
   首页的功能主要是显示一级分类和二级分类,每个二级分类根据Class判断所属于那个一级栏目。
   
页面功能的实现
实现思想

   根据页面的需求,需要从数据库查询所有的一级栏目和二级栏目,二级栏目根据Class字段判断所属于的一级栏目,通过Repeater嵌套实现循环输出。

  显示一级栏目的Repeater_Class1通过设置DataSourceID属性从ObjectDataSource—ObjectDataSource_Class1获取数据源,绑定到Repeater_Class1。ObjectDataSource是.Net2.0的新控件之一,是为快速开发“三层结构”而增加的,本身不能实现数据库直接读取。在.Net2.0当中实现“三层结构”非常简单,能够使用很少的代码编写完成整个过程。
创建数据层

   跟底层数据源相关的所有编码,譬如建立到数据库的连接,发出SELECT,INSERT ,UPDATE,和DELETE命令等的编码,都应该放置在DAL中。表现层不应该包含对这些数据访问编码的任何引用,而应该调用数据层DAL(Data Access Layer)中的编码来作所有的数据访问请求。

   在App_Code/DAL/目录下新建一个数据集XSD文件ClassDAL.xsd,该文件所实现的功能是所有对Class1、Class2的查询、修改、删除等操作,根据向导设置好一些查询语句,而不用自己手写代码。数据集XSD文件利用Xml格式生成强类型的,利用比如实现首页查询的GetData方法。

  这些方法,被调用后,将连接到数据库,发出合适的查询,然后返回结果。我们如何返回这些结果是很重要的 。这些方法可以直接返回数据库查询填充的DataSet 或者DataReader ,但理想的办法是把这些结果以强类型对象的形式返回。一个强类型的对象,其schema是编译时严格定义好的,而相比之下,弱类型的对象, 其schema在运行时之前是未知的。

  譬如,DataReader和普通的DataSet是弱类型对象,因为它们的schema是被用来填充它们的数据库查询返回的字段来定义的。要访问弱类型DataTable中的一个特定字段,我们需要用这样的句法:DataTable.Rows ["columnName"]。这个DataTable的弱类型性质表现在于,我们需要通过一个字符串或序号索引来访问字段名称。而在另一个方面,一个强类型的DataTable,它的所有的字段都是通过属性的形式来实现的 ,访问的编码就会象这样:DataTable.Rows.columnName。

  要返回强类型对象,我们可以创建自定义业务对象,或者使用强类型的DataSet。开发人员实现的业务对象类,其属性往往是对相应的底层数据表的字段的映射。而一个强类型的DataSet,则是Visual Studio基于数据库schema为你生成的一个类,其成员的类型都是由这个schema决定的。强类型的DataSet本身,是由继承 于ADO.NET中DataSet,DataTable,和DataRow类的子类组成的。除了强类型的DataTable外,强类型的DataSet现在还包括TableAdapter类,这些类包含了填充DataSet中的DataTable和把 DataTable的改动传回数据库的各种方法。

  强类型的DataSet起了强类型对象的集合的作用,它由强类型DataTable实例组成,每个强类型DataTable又进而由强类型的DataRow实例组成。我们将为这个论坛要用到的大部分数据表建立一个对应的强类型DataTable 。比如数据集XSD文件所生成的GetData方法。
强类型的DataTable并不包括如何访问对应底层的数据表的任何信息。要获取用来填充DataTable的数据 ,我们使用TableAdapter类,它提供了数据访问层的功能。对于ClassDAL.xsd的Class_1 DataTable,相应的TableAdapter类将包括GetData ()和GetDataBy_gid(@gid)等方法,而我们将在表现层调用这些方法。DataTable的作用是在分层间传输数据。
创建逻辑层
   通过数据访问层已经清晰地将表示逻辑与数据访问逻辑区分开了。不过,即使DAL将数据访问的细节从表示层中分离出来了,可它却不能处理任何的业务规则。仅仅是只能从数据库中提取数据而已。我们其实可以将业务逻辑层(Business Logic Layer)看作是在数据访问层和表示层之间进行数据交换的桥梁,在一个实际的应用程序中,BLL都是以类库(Class Library)的形式来实现的,不过为了简化工程的结构,在论坛中我们将BLL实现为App_Code文件夹中的一系列的类。

   我们在App_Code/BLL/下新建一个ClassBLL.cs,ClassBLL从ClassDAL.xsd的TableAdapter中得到读取、插入、修改以及删除等方法以应用合适的业务规则。下面我们来看下如果在逻辑层中获取数据层ClassDAL.xsd内的数据。
在ClassBLL.cs中

private static DAL_Class_1_TableAdapter _Adapter_Class_1 = null;    protected static DAL_Class_1_TableAdapter Adapter_Class_1    {      get      {            if (_Adapter_Class_1 == null)                _Adapter_Class_1 = new DAL_Class_1_TableAdapter();            return _Adapter_Class_1;      }    }DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]    public ClassDAL.Class_1DataTable BLL_GetData_DB_Class1()    {      return Adapter_Class_1.GetData();}

  我们先定义一个ClassDAL.xsd内的TableAdapterDAL_Class_1_TableAdapter_Adapter_Class_1,然后使用_Adapter_Class_1来返回一个DAL_Class_1_TableAdapterAdapter_Class_1,它它提供了数据访问层的功能,然后,我们还需要定义一个强类型的DataTableBLL_GetData_DB_Class1,同样这个强类型的DataTable是我们在数据层所制作的Class_1DataTable。前面也说过,强类型的DataTable并不包括如何访问对应底层的数据表的任何信息。我们使用了TableAdapter Adapter_Class_1获取用来填充BLL_GetData_DB_Class1的数据。

         为了能在表现层能够通过ObjectDataSource获取这个DataTable内的数据,我们需要在BLL_GetData_DB_Class1上加入以下代码: DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]    这样就能够为和表现层的ObjectDataSource联系做好了准备。   一个具有良好架构的应用程序都拥有清晰的层次结构,每一个层次都封装了一个特定的角色。我们已经用类型化数据集创建了一个数据访问层,和一个业务逻辑层,它由App_Code中一系列的类构成,并调用DAL中相应的方法。BLL为我们的应用程序实现了字段级和业务级的逻辑。

  这段编码不要求我们写一行的跟数据访问有关的编码。我们不需要生成任何ADO.NET类的实例,我们不需要指明任何连接字符串,任何SQL查询语句,或者任何存储过程。TableAdapter为我们提供了底层的数据访问编码。到此,我们已经完成了需要为论坛首页显示一级栏目所需要的数据库底层操作。由于目前实现这一功能不需要任何业务逻辑,所以在BLL_GetData_DB_Class1中直接返回GetData中的Class_1DataTable。

完成表示层

   在表示层,我们需要放置一个Repeater Repeater_Class1用于显示一级栏目。由于我们在逻辑层中已经完成了获取数据的所有操作,我们在表示层所需要做的很简单,只需要添加一个ObjectDataSource,并且设置SelectMethod="BLL_GetData_DB_Class1"
与TypeName="ClassBLL",指定到业务层我们所做的那个BLL_GetData_DB_Class1中,然后在Repeater_Class1中指定DataSourceID="ObjectDataSource_Class1"就可以完成把数据绑定到Repeater的这样一个过程了,当然,这个过程不需要我们写一行代码,只需要根据向导来做既可。

   Repeater给予了我们非常大的灵活性,也正是由于它简单的功能使得它具有在性能上的优势。利用获取每个字段的数据。通常我们会选择使用DataBinder.Eval 来绑定数据,如:,但是DataBinder.Eval是用于晚期绑定的静态方法。虽然它的语法可能比标准数据绑定语法简单,但性能较差。所以在这里我们使用直接查询DataRowView的Row来获取数据。虽然说Row[“ID”]这样更直观些,但是使用Row索引符却能带来更好的性能。

   到此,一级栏目已经能够实现输出了,但是还缺少二级栏目的显示,二级栏目是在一级栏目内显示的,所以我们需要使用嵌套Repeater来循环显示二层的数据,实现方法有二种:第一种是里层的Repeater根据外层Repeater的ID值查询二级分类表获得该二级栏目的内容。这种方法虽然可以行,但是每次绑定到外层Repeater时,都会触发内层Repeater去数据库查询相对应的二级数据。假使一个页面有3个一级分类,这样页面刷新一次就需要1+3=4次查询,一级栏目越多,查询的次数也约多。对于一个论坛来说和数据库的操作是非常耗时耗资源的,所以我们必须考虑其他方法,既第二种方法。

  通过页面的分析,其实我们只是需要获得二个表的数据。既一级栏目的所有数据和二级栏目的所有数据,所以我们其实可以只需要查询数据库二次就可以完成所有数据的读取,然后通过DataTable的RowFilter功能把二级栏目和一级栏目对应起来既可。所以在我们已经实现显示一级栏目的基础下,分别在逻辑和数据层设置好查询所有二级栏目的功能,既ClassBLL的BLL_GetData_DB_Class2,该方法实现查询所有的二级栏目内容。然后在首页的.cs里面这样设置。

    //定义一个DataTable    protected static DataTable Class2_DataTable = new DataTable();    //当页面第一次加载时候从数据库提取所有二级栏目的DataTable填充到Class2_DataTable里面    protected void Page_Load(object sender, EventArgs e)    {      if (!IsPostBack)      {            ClassBLL _ClassBll = new ClassBLL();            Class2_DataTable = _ClassBll.BLL_GetData_DB_Class2();      }    }    //这样每次执行到Repeater_Class2时候只需要从Class2_DataTable里面通过RowFilter    //提取本一级栏目分类的数据就行了,整个页面只需要查询数据库二次就能够提取所有数据    protected DataTable GetClass2(int Class1)    {      DataTable Class2_DataTable_RowFilter = Class2_DataTable;      Class2_DataTable_RowFilter.DefaultView.RowFilter = "Class = " + Class1;      return Class2_DataTable_RowFilter;}
  在页面第一次加载时通过一个DataTable Class2_DataTable把所有二级分类的数据存放到里面。然后在Repeater_Class2里面设置其数据源DataSource的值为,通过GetClass2传入一级栏目的ID然后返回对应的二级栏目的DataTable。从而实现二次查询完成整个页面的功能。



打字也是很辛苦的,有兴趣就看下吧,是程序的说明文档,目前只写到这里而已。


[ 本帖最后由 因为帅烦 于 2006-12-28 23:28 编辑 ]

wei50922 发表于 2006-12-29 10:33:55

:) 曾听某某老师说,04级信息班有个网页制作牛人叫黄亮,
不知道楼主是否认识,或者是本人~

因为帅烦 发表于 2006-12-29 19:20:47

打网络游戏得到一个极品装备,价值 811 思明论坛!

   下次努力哦!……那个呀 不就是Linsie吗:)

haxc 发表于 2007-1-6 19:37:27

无缘无故有名人请你吃饭,还赠送 196 思明论坛,热心值加 2 !

   下次努力哦!……做一个install.asp吧,现在这种程度的连beta都算不上,打算学php,不过还没头绪

欣云 发表于 2007-1-6 23:00:49

原帖由 haxc 于 2007-1-6 19:37 发表
做一个install.asp吧,现在这种程度的连beta都算不上,打算学php,不过还没头绪


什么样的程度才算beta呢?~~偶搞了那么久程序都没看懂这句话`````:L :Q

因为帅烦 发表于 2007-1-12 16:17:26

做生意遇贵人相助,一天净赚 5965 思明论坛!

   下次努力哦!……晕 , 光做这个站点都耗了很多时间
install.asp嘛给钱的话可以做
不然还不如把时间用在找工作上呢
页: [1]
查看完整版本: [原创]新站发布测试版本 - GZBBS [源代码+数据库] ■■■■■■■■■