日期:2014-01-02  浏览次数:20478 次

翻译:刘海东

以下内容翻译自Building Websites with the ASP.NET Community Starter Kit by K. Scott Allen and Cristian Darie for Packt Publishing,以下内容是该书的第8章,详细介绍如何扩展CSK来增加FAQ功能. 如果你想了解 ASP.NET Community Starter Kit的详细信息,可以到www.asp.net浏览和下载,它是一个免费的开源项目.假如你想建造一个稳健而灵活的ASP.NET网站,CSK将是一个很好的出发点.

创建一个新模块
每一个社区网站都会有不同的需求要实现。虽然本身的CSK类库有很大的灵活性,但完全拥有源代码意味者你可以在这个高品质的网站基础上增加定制的额外功能。在这篇文章里,我们将详细介绍如何在已有的框架中增加一个全新的功能FAQ(Frequently Asked Questions),并如何做到与已有的模块无缝衔接。

在真正开始之前,先提醒大家一下,CSK是一个不断修改和升级的项目,所以在动手增加新模块之前,先到网上查找一下别人是否已经实现了这项功能,或者关注一下CSK是否增加了新的特性。

模块设计
在你实现一个用于CSK的模块之前,首先要明白你要增加的特性到底是什么,然后决定由CSK中已有的哪些模块来实现这个功能。

首先让我们对FAQ的需求列一个大致的清单:

l 一个FAQ由一个问题、一个答案,一个描述或介绍和一些相关参照的链接组成,

l 社区成员能够对某个问题加评注或评级,当有新的问题时通过邮件提醒,

l 如果版主同意,社区成员可以发布新的问题主题。

你当然可以只用一个HTML文件列出所以的问题和答案,但那样就限制了用户的交互性操作(评注、评级、邮件等)

在CSK所附带的数据库中有表Community_ContentPages,其中包含了社区页面的大部分信息如作者、浏览计数和介绍等。由于要存放与FAQ相关的答案、参考链接等属性,我们再增加一个表Community_Faqs:


然后我们可以创建保存FAQ信息的类了。在下面的图中,FaqInfo类继承自ContentInfo,它可以保存一般内容信息项的大部分属性。每一个模块都会有一个自己的Utility类来读取、添加和编辑内容。所以对于FAQ的模块,我们还要创建一个FaqUtility类。


我们还要创建给Code-Behind页面使用的类来显示和编辑FAQ。CSK中是通过SkinnedCommunityControl来使不同页面显示不同的界面。CSK中也包含了其它实现了常用功能的基类可用于增加(ContentAddPage),编辑(ContentEditPage)和显示(ContentItemPage),下面的图中显示了这些类的继承关系


另外,我们还需要创建从WebControl继承的类来显示FAQ的内容。通常,每一个属性显示时放在不同的控件中,并且该控件可以用最适合的风格来显示内容。下面的图中显示了这些最终在这个模块中会使用的控件,它们最终都是从WebControl继承而来。


模块创建过程
构建模块的过程我们将采用自底向上底方式,从数据库建立开始,到表现层的界面和主题设置结束。我们将沿用在CSK中已经约定的命名模式,保持与其它模块的风格一致。如,在书的模块中要从Community_Books表中读取信息,那么相应的类就是BookInfo。

这样我们就用一个叫做Community_Faqs的表,对应的类叫做FaqInfo。当然你可能想另外加上唯一标示防止将来的CSK中包含这个模块。例如你在ABC公司工作,那么这个表名可以叫做Community_ABCFaqs来减少将来可能出现的名称冲突。

我们将使用下面的步骤来构建FAQ模块。你可以参照这些步骤构建你自己的模块:

1. 创建一个新的表(Community_FAqs)来保存新模块的附加字段信息,

2. 创建用于添加、编辑、和选择一个FAQ的存储过程,另外还要一个从给定范围内读取所有FAQ的存储过程,

3. 创建一个维护的存储过程通过填充Community_PageTypes和Community_NamedPages表来初始化FAQ模块,

4. 创建一个FaqInfo的类保存一条FAQ的信息,

5. 创建一个FaqUtility的类通过访问数据库来调用前面创建的与FAQ相关的存储过程,

6. 创建从WebControl继承的控件显示不同的字段,这些控件叫做FaqQuestion,FaqInro,FaqAnswer,FaqReference和FaqEditContent

7. 创建从SkinnedCommunityControl继承的类来包含下一步创建的显示页面背后的逻辑。这些类叫做AddFaq,EditFaq,FaqSection,和Faq

8. 创建新模块使用的内容显示页面,包括有Faqs_AddFaq.ascx,Faqs_FaqSection.ascx和Faq_Faq.ascx。我们将使用Faqs_AddFaq增加和编辑FAQ。另外你还要在Communityes\Common\Themes\Defalult\Skins\ContentSkins目录下创建默认界面文件,例如Robotics和Professional的主题。

9. 创建定义该模块页面风格的CSS文件和主题相关的CSS文件,并放到Communities\Common\Themes\Defalult\Styles。

下面将对每一个步骤作详细的解释。

Community_Faq表
大部分模块共有的信息如标题、描述和浏览计数放在Community_ContentPages表中。针对该FAQ模块的附加信息则需要另加一个表存放。例如,我们可以把FAQ的问题放在Page_title字段中,FAQ的介绍放在Page_description字段.另外,我们还需要存放FAQ的答案和附加的参考索引等信息,所以还要创建下面的表:

CREATE TABLE [Community_Faqs] (

[Faq_ContentPageID] [int] NOT NULL ,

[Faq_Answer] [ntext] NOT NULL ,

[Faq_Reference] [ntext] NULL,

CONSTRAINT [PK_Community_Faqs] PRIMARY KEY CLUSTERED

(

[Faq_ContentPageID]

),

CONSTRAINT [FK_Community_Faqs_Community_ContentPages]

FOREIGN KEY

(

[Faq_ContentPageID]

) REFERENCES [Community_ContentPages] (

[contentPage_id]

) ON DELETE CASCADE

可以看到表的命名方式和数据类型与CSK中的其它模块都是一致的,这样的编程习惯在国内实在是难以做到。

我们存储FAQ的答案和参考索引的字段是ntext类型,这是为了能支持大数据量的文本(可高达1GB)。还要注意的是Faq_Answer是一个必要字段而Faq_Reference可以是空值。我们的主键(Faq_ContentpageID)关联到Community_Contentpages表中的附加内容。另外一个要注意的细节是外键的约束(级联删除)的使用,保证的数据关联的完整性,并且节省了程序代码。

CSK使用名为Community_ContentpagesDeleteContentPage(太长了吧)的存储过程删除Community_ContentPages表中的记录。当这个存储过程删除记录时,服务器根据外键自动删除FAQ表中的对应记录。

增加存储过程
下面我们要做的是建立增加、编辑、读取单个、读取多个记录的存储过程,在代码中不会出现SQL的代码。从封装性和安全性来看,这样做是一种很好的习惯。

Community_FaqsAddFaq
下面是增加一条新的FAQ记录的存储过程。我们不需要给两个表中的每个字段填充