Cuyahoga
国外的开源CMS一般都是基于模块设计的 ,好处是可以随意定制自己的页面和模块,这样在以后的应用中就能够灵活的满足变化的功能需求. 一个模块齐全的CMS如DNN , Rainbow就可以快速搭建符合需求的系统.
下面就来介绍如何为Cuyahoga这个著名的开源网站框架加入具有后台管理的公告模块.可以参考这篇如何在Cuyahoga中新增一个简单的功能模块了解基础的步骤.
为Cuyahoga开发自定义模块时,你可以选择任何数据访问策略.然而Cuyahoga本身是使用NHibernate作为数据持久层,可以做到支持多数据库. 采用Castle.Windsor进行依赖注入,降低模块之间的耦合. 我们的数据访问层也将用NHibernate实现.
最终项目的目录结构如下:
主要步骤如下
1 .创建一个Sql文件(Install.sql)用来安装数据表及添加模块的相关信息 , 该sql文件会在安装模块时,由Cuyahoga自动执行.也可以手工执行进行安装.
2.创建域模型 在本例中是实体类
3.创建映射文件
4.创建公告模块的核心控制类
5.创建用于前台显示的用户控件 用来显示公告的标题 作者和发布时间.
6.创建公告管理的列表页面
7.创建公告管理的具体页面
到此就完成了公告模块的开发 在后台页面将模块添加到前台页面就可以显示了.
可以改进的地方:
为模块添加url重写,在后台管理页面设置参数.Created by jecray
下面就来介绍如何为Cuyahoga这个著名的开源网站框架加入具有后台管理的公告模块.可以参考这篇如何在Cuyahoga中新增一个简单的功能模块了解基础的步骤.
为Cuyahoga开发自定义模块时,你可以选择任何数据访问策略.然而Cuyahoga本身是使用NHibernate作为数据持久层,可以做到支持多数据库. 采用Castle.Windsor进行依赖注入,降低模块之间的耦合. 我们的数据访问层也将用NHibernate实现.
最终项目的目录结构如下:
主要步骤如下
1 .创建一个Sql文件(Install.sql)用来安装数据表及添加模块的相关信息 , 该sql文件会在安装模块时,由Cuyahoga自动执行.也可以手工执行进行安装.
install.sql
IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[cm_Announcements]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [cm_Announcements] (
[AnnouncementsID] [int] IDENTITY (1,1)NOT NULL ,
[sectionid] [int] NOT NULL ,
[createdby] [nvarchar] (100) NULL ,//公告作者
[Title] [nvarchar] (150) NULL ,//公告标题
inserttimestamp datetime DEFAULT current_timestamp NOT NULL,
updatetimestamp datetime DEFAULT current_timestamp NOT NULL,
CONSTRAINT [PK_cm_Announcements] PRIMARY KEY NONCLUSTERED
(
[AnnouncementsID]
),
CONSTRAINT [FK_cm_Announcements_cm_Modules] FOREIGN KEY
(sectionid) REFERENCES cuyahoga_section (sectionid)
)
END
GO
/*加入模块信息*/
INSERT INTO cuyahoga_moduletype ([name], assemblyname, classname, path, editpath, inserttimestamp, updatetimestamp) VALUES
('Announcements', 'Cuyahoga.Modules.Announcements', 'Cuyahoga.Modules.Announcements.AnnouncementsModule',
'Modules/Announcements/Announcements.ascx', 'Modules/Announcements/EditAnnouncements.aspx', current_timestamp, current_timestamp)
GO
/*加入模块版本信息*/
INSERT INTO cuyahoga_version (assembly, major, minor, patch) VALUES ('Cuyahoga.Modules.Announcements', 1, 5, 0);
go
IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[cm_Announcements]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [cm_Announcements] (
[AnnouncementsID] [int] IDENTITY (1,1)NOT NULL ,
[sectionid] [int] NOT NULL ,
[createdby] [nvarchar] (100) NULL ,//公告作者
[Title] [nvarchar] (150) NULL ,//公告标题
inserttimestamp datetime DEFAULT current_timestamp NOT NULL,
updatetimestamp datetime DEFAULT current_timestamp NOT NULL,
CONSTRAINT [PK_cm_Announcements] PRIMARY KEY NONCLUSTERED
(
[AnnouncementsID]
),
CONSTRAINT [FK_cm_Announcements_cm_Modules] FOREIGN KEY
(sectionid) REFERENCES cuyahoga_section (sectionid)
)
END
GO
/*加入模块信息*/
INSERT INTO cuyahoga_moduletype ([name], assemblyname, classname, path, editpath, inserttimestamp, updatetimestamp) VALUES
('Announcements', 'Cuyahoga.Modules.Announcements', 'Cuyahoga.Modules.Announcements.AnnouncementsModule',
'Modules/Announcements/Announcements.ascx', 'Modules/Announcements/EditAnnouncements.aspx', current_timestamp, current_timestamp)
GO
/*加入模块版本信息*/
INSERT INTO cuyahoga_version (assembly, major, minor, patch) VALUES ('Cuyahoga.Modules.Announcements', 1, 5, 0);
go
2.创建域模型 在本例中是实体类
Announcement.cs
using System;
using Cuyahoga.Core.Domain;
namespace Cuyahoga.Modules.Announcements.Domain
{
public class Announcement
{
private int _id;
private string _title;
private string _content;
private DateTime _expiredate;
private Section _section;
private User _createdBy;
private DateTime _updateTimestamp;
/// <summary>
/// Property Id (int)
/// </summary>
public int Id
{
get { return this._id; }
set { this._id = value; }
}
/// <summary>
/// Property Title (string)
/// </summary>
public string Title
{
get { return this._title; }
set { this._title = value; }
}
/// <summary>
/// Property Section (Section)
/// </summary>
public Section Section
{
get { return this._section; }
set { this._section = value; }
}
/// <summary>
/// Property CreatedBy (User)
/// </summary>
public User CreatedBy
{
get { return this._createdBy; }
set { this._createdBy = value; }
}
/// <summary>
/// Property UpdateTimestamp (DateTime)
/// </summary>
public DateTime UpdateTimestamp
{
get { return this._updateTimestamp; }
set { this._updateTimestamp = value; }
}
public Announcement()
{
this._id = -1;
}
}
}
using System;
using Cuyahoga.Core.Domain;
namespace Cuyahoga.Modules.Announcements.Domain
{
public class Announcement
{
private int _id;
private string _title;
private string _content;
private DateTime _expiredate;
private Section _section;
private User _createdBy;
private DateTime _updateTimestamp;
/// <summary>
/// Property Id (int)
/// </summary>
public int Id
{
get { return this._id; }
set { this._id = value; }
}
/// <summary>
/// Property Title (string)
/// </summary>
public string Title
{
get { return this._title; }
set { this._title = value; }
}
/// <summary>
/// Property Section (Section)
/// </summary>
public Section Section
{
get { return this._section; }
set { this._section = value; }
}
/// <summary>
/// Property CreatedBy (User)
/// </summary>
public User CreatedBy
{
get { return this._createdBy; }
set { this._createdBy = value; }
}
/// <summary>
/// Property UpdateTimestamp (DateTime)
/// </summary>
public DateTime UpdateTimestamp
{
get { return this._updateTimestamp; }
set { this._updateTimestamp = value; }
}
public Announcement()
{
this._id = -1;
}
}
}
3.创建映射文件
Announcement.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="Cuyahoga.Modules.Announcements.Domain.Announcement, Cuyahoga.Modules.Announcements" table="cm_Announcements">
<id name="Id" column="Announcementsid" type="Int32" unsaved-value="-1">
<generator class="native">
<param name="sequence">cm_Announcements_Announcementsid_seq</param>
</generator>
</id>
<timestamp name="UpdateTimestamp" column="updatetimestamp" />
<property name="Title" column="title" type="String" length="150" />
<many-to-one name="Section" class="Cuyahoga.Core.Domain.Section, Cuyahoga.Core" column="sectionid" not-null="true" />
<many-to-one name="CreatedBy" class="Cuyahoga.Core.Domain.User, Cuyahoga.Core" column="createdby" not-null="true" />
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="Cuyahoga.Modules.Announcements.Domain.Announcement, Cuyahoga.Modules.Announcements" table="cm_Announcements">
<id name="Id" column="Announcementsid" type="Int32" unsaved-value="-1">
<generator class="native">
<param name="sequence">cm_Announcements_Announcementsid_seq</param>
</generator>
</id>
<timestamp name="UpdateTimestamp" column="updatetimestamp" />
<property name="Title" column="title" type="String" length="150" />
<many-to-one name="Section" class="Cuyahoga.Core.Domain.Section, Cuyahoga.Core" column="sectionid" not-null="true" />
<many-to-one name="CreatedBy" class="Cuyahoga.Core.Domain.User, Cuyahoga.Core" column="createdby" not-null="true" />
</class>
</hibernate-mapping>
4.创建公告模块的核心控制类
AnnouncementsModule.cs
using System;
using System.Collections;
using System.Xml;
using System.Xml.XPath;
using System.Net;
using System.Web;
using System.Text;
using System.IO;
using System.Threading;
using NHibernate;
using Castle.Services.Transaction;
using Castle.Facilities.NHibernateIntegration;
using log4net;
using Cuyahoga.Core;
using Cuyahoga.Core.Domain;
using Cuyahoga.Core.Service;
using Cuyahoga.Core.Util;
using Cuyahoga.Web.Util;
using Cuyahoga.Web.Components;
using Cuyahoga.Modules.Announcements.Domain;
namespace Cuyahoga.Modules.Announcements
{
//采用Facilities管理事务
[Transactional]
public class AnnouncementsModule : ModuleBase, INHibernateModule
{
private static readonly ILog log = LogManager.GetLogger(typeof(AnnouncementsModule));
private int _cacheDuration;
private ISessionManager _sessionManager;
//该模块需要用到NHibernate session manager提供的服务 进行依赖注入
public AnnouncementsModule(ISessionManager sessionManager)
{
this._sessionManager = sessionManager;
}
public override void ReadSectionSettings()
{
base.ReadSectionSettings();
// Set dynamic module settings
this._cacheDuration = Convert.ToInt32(base.Section.Settings["CACHE_DURATION"]);
}
///不创建子事务
[Transaction(TransactionMode.RequiresNew)]
public virtual IList GetAllAnnouncements()
{
ISession session = this._sessionManager.OpenSession();
string hql = "from Announcement f where f.Section.Id = :sectionId";
IQuery q = session.CreateQuery(hql);
q.SetInt32("sectionId", base.Section.Id);
return q.List();
}
[Transaction(TransactionMode.RequiresNew)]
public virtual Announcement GetAnnouncementsById(int AnnouncementsID)
{
ISession session = this._sessionManager.OpenSession();
return (Announcement)session.Load(typeof(Announcement), AnnouncementsID);
}
[Transaction(TransactionMode.RequiresNew)]
public virtual void SaveAnnouncement(Announcement announcements)
{
ISession session = this._sessionManager.OpenSession();
session.SaveOrUpdate(announcements);
}
[Transaction(TransactionMode.RequiresNew)]
public virtual void DeleteAnnouncements(Announcement announcements)
{
ISession session = this._sessionManager.OpenSession();
session.Delete(announcements);
}
}
}
using System;
using System.Collections;
using System.Xml;
using System.Xml.XPath;
using System.Net;
using System.Web;
using System.Text;
using System.IO;
using System.Threading;
using NHibernate;
using Castle.Services.Transaction;
using Castle.Facilities.NHibernateIntegration;
using log4net;
using Cuyahoga.Core;
using Cuyahoga.Core.Domain;
using Cuyahoga.Core.Service;
using Cuyahoga.Core.Util;
using Cuyahoga.Web.Util;
using Cuyahoga.Web.Components;
using Cuyahoga.Modules.Announcements.Domain;
namespace Cuyahoga.Modules.Announcements
{
//采用Facilities管理事务
[Transactional]
public class AnnouncementsModule : ModuleBase, INHibernateModule
{
private static readonly ILog log = LogManager.GetLogger(typeof(AnnouncementsModule));
private int _cacheDuration;
private ISessionManager _sessionManager;
//该模块需要用到NHibernate session manager提供的服务 进行依赖注入
public AnnouncementsModule(ISessionManager sessionManager)
{
this._sessionManager = sessionManager;
}
public override void ReadSectionSettings()
{
base.ReadSectionSettings();
// Set dynamic module settings
this._cacheDuration = Convert.ToInt32(base.Section.Settings["CACHE_DURATION"]);
}
///不创建子事务
[Transaction(TransactionMode.RequiresNew)]
public virtual IList GetAllAnnouncements()
{
ISession session = this._sessionManager.OpenSession();
string hql = "from Announcement f where f.Section.Id = :sectionId";
IQuery q = session.CreateQuery(hql);
q.SetInt32("sectionId", base.Section.Id);
return q.List();
}
[Transaction(TransactionMode.RequiresNew)]
public virtual Announcement GetAnnouncementsById(int AnnouncementsID)
{
ISession session = this._sessionManager.OpenSession();
return (Announcement)session.Load(typeof(Announcement), AnnouncementsID);
}
[Transaction(TransactionMode.RequiresNew)]
public virtual void SaveAnnouncement(Announcement announcements)
{
ISession session = this._sessionManager.OpenSession();
session.SaveOrUpdate(announcements);
}
[Transaction(TransactionMode.RequiresNew)]
public virtual void DeleteAnnouncements(Announcement announcements)
{
ISession session = this._sessionManager.OpenSession();
session.Delete(announcements);
}
}
}
5.创建用于前台显示的用户控件 用来显示公告的标题 作者和发布时间.
Announcements.ascx
<%@ Control Language="C#" AutoEventWireup="true" Codebehind="Announcements.ascx.cs"
Inherits="Cuyahoga.Modules.Announcements.Web.Announcements" %>
<asp:repeater id="rptAnnouncementItems" runat="server" enableviewstate="False">
<itemtemplate>
<div class="genericdetails" style="width:100%">
<marquee direction="left" >
<asp:label id="lblTitle" runat="server"><%# DataBinder.Eval(Container.DataItem, "Title")%></asp:label>
<asp:label id="lblAuthor" runat="server">作者:<%# DataBinder.Eval(Container.DataItem, "CreatedBy.FullName")%></asp:label>
<asp:label id="lblTime" runat="server">发布时间:<%# DataBinder.Eval(Container.DataItem, "UpdateTimestamp")%></asp:label>
</marquee>
</div>
</itemtemplate>
</asp:repeater>
<%@ Control Language="C#" AutoEventWireup="true" Codebehind="Announcements.ascx.cs"
Inherits="Cuyahoga.Modules.Announcements.Web.Announcements" %>
<asp:repeater id="rptAnnouncementItems" runat="server" enableviewstate="False">
<itemtemplate>
<div class="genericdetails" style="width:100%">
<marquee direction="left" >
<asp:label id="lblTitle" runat="server"><%# DataBinder.Eval(Container.DataItem, "Title")%></asp:label>
<asp:label id="lblAuthor" runat="server">作者:<%# DataBinder.Eval(Container.DataItem, "CreatedBy.FullName")%></asp:label>
<asp:label id="lblTime" runat="server">发布时间:<%# DataBinder.Eval(Container.DataItem, "UpdateTimestamp")%></asp:label>
</marquee>
</div>
</itemtemplate>
</asp:repeater>
Announcements.ascx.cs
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Cuyahoga.Core.Util;
using Cuyahoga.Web.UI;
using Cuyahoga.Modules.Announcements.Domain;
namespace Cuyahoga.Modules.Announcements.Web
{
public partial class Announcements : BaseModuleControl
{
private AnnouncementsModule _module;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack && !base.HasCachedOutput)
{
this._module = base.Module as AnnouncementsModule;
this.rptAnnouncementItems.DataSource = this._module.GetAllAnnouncements();
this.rptAnnouncementItems.DataBind();
}
}
}
}
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Cuyahoga.Core.Util;
using Cuyahoga.Web.UI;
using Cuyahoga.Modules.Announcements.Domain;
namespace Cuyahoga.Modules.Announcements.Web
{
public partial class Announcements : BaseModuleControl
{
private AnnouncementsModule _module;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack && !base.HasCachedOutput)
{
this._module = base.Module as AnnouncementsModule;
this.rptAnnouncementItems.DataSource = this._module.GetAllAnnouncements();
this.rptAnnouncementItems.DataBind();
}
}
}
}
6.创建公告管理的列表页面
EditAnnouncements.aspx
<%@ Page Language="C#" AutoEventWireup="true" Codebehind="EditAnnouncements.aspx.cs"
Inherits="Cuyahoga.Modules.Announcements.Web.EditAnnouncements" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>公告管理页面</title>
</head>
<body>
<form id="Form1" method="post" runat="server">
<div id="moduleadminpane">
<h1>
公告管理</h1>
<table class="tbl">
<asp:Repeater ID="rptAnnouncements" runat="server" OnItemDataBound="rptFiles_ItemDataBound">
<HeaderTemplate>
<tr>
<th>
公告标题</th>
<th>
作者</th>
<th>
发布日期</th>
<th>
</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<%# DataBinder.Eval(Container.DataItem, "Title") %>
</td>
<td>
<%# DataBinder.Eval(Container.DataItem, "CreatedBy.FullName")%>
</td>
<td>
<asp:Literal ID="litDateModified" runat="server"></asp:Literal></td>
<td>
<asp:HyperLink ID="hplEdit" runat="server">修改</asp:HyperLink>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
<br />
<input id="btnNew" type="button" value="新的公告" runat="server" name="btnNew"/>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" AutoEventWireup="true" Codebehind="EditAnnouncements.aspx.cs"
Inherits="Cuyahoga.Modules.Announcements.Web.EditAnnouncements" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>公告管理页面</title>
</head>
<body>
<form id="Form1" method="post" runat="server">
<div id="moduleadminpane">
<h1>
公告管理</h1>
<table class="tbl">
<asp:Repeater ID="rptAnnouncements" runat="server" OnItemDataBound="rptFiles_ItemDataBound">
<HeaderTemplate>
<tr>
<th>
公告标题</th>
<th>
作者</th>
<th>
发布日期</th>
<th>
</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<%# DataBinder.Eval(Container.DataItem, "Title") %>
</td>
<td>
<%# DataBinder.Eval(Container.DataItem, "CreatedBy.FullName")%>
</td>
<td>
<asp:Literal ID="litDateModified" runat="server"></asp:Literal></td>
<td>
<asp:HyperLink ID="hplEdit" runat="server">修改</asp:HyperLink>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
<br />
<input id="btnNew" type="button" value="新的公告" runat="server" name="btnNew"/>
</div>
</form>
</body>
</html>
EditAnnouncements.aspx.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Cuyahoga.Core.Domain;
using Cuyahoga.Core.Util;
using Cuyahoga.Web.UI;
using Cuyahoga.Modules.Announcements.Domain;
namespace Cuyahoga.Modules.Announcements.Web
{
public partial class EditAnnouncements : ModuleAdminBasePage
{
private AnnouncementsModule _module;
protected void Page_Load(object sender, EventArgs e)
{
// The base page has already created the module, we only have to cast it here to the right type.
this._module = base.Module as AnnouncementsModule;
this.btnNew.Attributes.Add("onclick", String.Format("document.location.href=
'EditAnnouncement.aspx{0}&AnnouncementId=-1'",
base.GetBaseQueryString()));
if (!this.IsPostBack)
{
BindFiles();
}
}
private void BindFiles()
{
this.rptAnnouncements.DataSource = this._module.GetAllAnnouncements();
this.rptAnnouncements.DataBind();
}
protected void rptFiles_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
Announcement announce = e.Item.DataItem as Announcement;
Literal litDateModified = e.Item.FindControl("litDateModified") as Literal;
if (litDateModified != null)
{
litDateModified.Text = TimeZoneUtil.AdjustDateToUserTimeZone(announce.UpdateTimestamp, this.User.Identity).ToString();
}
HyperLink hplEdit = e.Item.FindControl("hpledit") as HyperLink;
if (hplEdit != null)
{
hplEdit.NavigateUrl = String.Format("~/Modules/Announcements/EditAnnouncement.aspx{0}&AnnouncementId={1}", base.GetBaseQueryString(), announce.Id);
}
}
}
}
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Cuyahoga.Core.Domain;
using Cuyahoga.Core.Util;
using Cuyahoga.Web.UI;
using Cuyahoga.Modules.Announcements.Domain;
namespace Cuyahoga.Modules.Announcements.Web
{
public partial class EditAnnouncements : ModuleAdminBasePage
{
private AnnouncementsModule _module;
protected void Page_Load(object sender, EventArgs e)
{
// The base page has already created the module, we only have to cast it here to the right type.
this._module = base.Module as AnnouncementsModule;
this.btnNew.Attributes.Add("onclick", String.Format("document.location.href=
'EditAnnouncement.aspx{0}&AnnouncementId=-1'",
base.GetBaseQueryString()));
if (!this.IsPostBack)
{
BindFiles();
}
}
private void BindFiles()
{
this.rptAnnouncements.DataSource = this._module.GetAllAnnouncements();
this.rptAnnouncements.DataBind();
}
protected void rptFiles_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
Announcement announce = e.Item.DataItem as Announcement;
Literal litDateModified = e.Item.FindControl("litDateModified") as Literal;
if (litDateModified != null)
{
litDateModified.Text = TimeZoneUtil.AdjustDateToUserTimeZone(announce.UpdateTimestamp, this.User.Identity).ToString();
}
HyperLink hplEdit = e.Item.FindControl("hpledit") as HyperLink;
if (hplEdit != null)
{
hplEdit.NavigateUrl = String.Format("~/Modules/Announcements/EditAnnouncement.aspx{0}&AnnouncementId={1}", base.GetBaseQueryString(), announce.Id);
}
}
}
}
7.创建公告管理的具体页面
EditAnnouncement.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EditAnnouncement.aspx.cs" Inherits="Cuyahoga.Modules.Announcements.Web.EditAnnouncement" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>修改公告页面</title>
</head>
<body>
<form id="Form1" method="post" runat="server">
<div id="moduleadminpane">
<h1>
修改公告</h1>
<div class="group">
<h4>
公告信息</h4>
<table>
<tr>
<td style="width: 100px">
标题:</td>
<td>
<asp:TextBox ID="txtTitle" runat="server" Width="300px"></asp:TextBox>
<asp:RequiredFieldValidator ID="rfTitle" runat="server" ErrorMessage="输入标题"
Display="Dynamic" CssClass="validator" ControlToValidate="txtTitle" EnableClientScript="False"></asp:RequiredFieldValidator>
</td>
</tr>
</table>
</div>
<p>
<asp:Button ID="btnSave" runat="server" Text="保存" OnClick="btnSave_Click"></asp:Button><asp:Button ID="btnDelete"
runat="server" Visible="False" CausesValidation="False" Text="删除" OnClick="btnDelete_Click"></asp:Button><asp:Button
ID="btnCancel" runat="server" CausesValidation="False" Text="取消" OnClick="btnCancel_Click"></asp:Button></p>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EditAnnouncement.aspx.cs" Inherits="Cuyahoga.Modules.Announcements.Web.EditAnnouncement" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>修改公告页面</title>
</head>
<body>
<form id="Form1" method="post" runat="server">
<div id="moduleadminpane">
<h1>
修改公告</h1>
<div class="group">
<h4>
公告信息</h4>
<table>
<tr>
<td style="width: 100px">
标题:</td>
<td>
<asp:TextBox ID="txtTitle" runat="server" Width="300px"></asp:TextBox>
<asp:RequiredFieldValidator ID="rfTitle" runat="server" ErrorMessage="输入标题"
Display="Dynamic" CssClass="validator" ControlToValidate="txtTitle" EnableClientScript="False"></asp:RequiredFieldValidator>
</td>
</tr>
</table>
</div>
<p>
<asp:Button ID="btnSave" runat="server" Text="保存" OnClick="btnSave_Click"></asp:Button><asp:Button ID="btnDelete"
runat="server" Visible="False" CausesValidation="False" Text="删除" OnClick="btnDelete_Click"></asp:Button><asp:Button
ID="btnCancel" runat="server" CausesValidation="False" Text="取消" OnClick="btnCancel_Click"></asp:Button></p>
</div>
</form>
</body>
</html>
EditAnnouncement.aspx.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Cuyahoga.Core.Domain;
using Cuyahoga.Web.UI;
using Cuyahoga.Modules.Announcements.Domain;
namespace Cuyahoga.Modules.Announcements.Web
{
public partial class EditAnnouncement : ModuleAdminBasePage
{
private AnnouncementsModule _module;
private int _announcementid;
private Announcement _announcement;
protected void Page_Load(object sender, EventArgs e)
{
// The base page has already created the module, we only have to cast it here to the right type.
this._module = base.Module as AnnouncementsModule;
this._announcementid = Int32.Parse(Request.QueryString["AnnouncementId"]);
if (this._announcementid > 0)
{
this._announcement = this._module.GetAnnouncementsById(this._announcementid);
if (!this.IsPostBack)
{
BindAnnouncement();
}
this.btnDelete.Visible = true;
this.btnDelete.Attributes.Add("onclick", "return confirm('Are you sure?');");
}
else
{
this._announcement = new Announcement();
this.btnDelete.Visible = false;
}
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
base.OnInit(e);
}
#endregion
private void BindAnnouncement()
{
this.txtTitle.Text = this._announcement.Title;
this.txtContent.Text = this._announcement.Content;
//this.calDatePublished.SelectedDate = this._file.DatePublished;
}
protected void btnSave_Click(object sender, EventArgs e)
{
if (this.IsValid)
{
this._announcement.CreatedBy = this.User.Identity as User;
this._announcement.Title = this.txtTitle.Text;
this._announcement.Content = this.txtContent.Text;
this._announcement.Section = base.Section;
//this._announcement.UpdateTimestamp = DateTime.Now;
this._announcement.ExpireDate = DateTime.Now.AddDays(5);
try
{
// Only save meta data.
this._module.SaveAnnouncement(this._announcement);
Context.Response.Redirect("EditAnnouncements.aspx" + base.GetBaseQueryString());
}
catch (Exception ex)
{
ShowError("Error saving file: " + ex.Message);
}
}
}
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
this._module.DeleteAnnouncements(this._announcement);
Context.Response.Redirect("EditAnnouncements.aspx" + base.GetBaseQueryString());
}
catch (Exception ex)
{
ShowError("Error deleting Announcements: " + ex.Message);
}
}
protected void btnCancel_Click(object sender, EventArgs e)
{
Context.Response.Redirect("EditAnnouncements.aspx" + base.GetBaseQueryString());
}
}
}
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Cuyahoga.Core.Domain;
using Cuyahoga.Web.UI;
using Cuyahoga.Modules.Announcements.Domain;
namespace Cuyahoga.Modules.Announcements.Web
{
public partial class EditAnnouncement : ModuleAdminBasePage
{
private AnnouncementsModule _module;
private int _announcementid;
private Announcement _announcement;
protected void Page_Load(object sender, EventArgs e)
{
// The base page has already created the module, we only have to cast it here to the right type.
this._module = base.Module as AnnouncementsModule;
this._announcementid = Int32.Parse(Request.QueryString["AnnouncementId"]);
if (this._announcementid > 0)
{
this._announcement = this._module.GetAnnouncementsById(this._announcementid);
if (!this.IsPostBack)
{
BindAnnouncement();
}
this.btnDelete.Visible = true;
this.btnDelete.Attributes.Add("onclick", "return confirm('Are you sure?');");
}
else
{
this._announcement = new Announcement();
this.btnDelete.Visible = false;
}
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
base.OnInit(e);
}
#endregion
private void BindAnnouncement()
{
this.txtTitle.Text = this._announcement.Title;
this.txtContent.Text = this._announcement.Content;
//this.calDatePublished.SelectedDate = this._file.DatePublished;
}
protected void btnSave_Click(object sender, EventArgs e)
{
if (this.IsValid)
{
this._announcement.CreatedBy = this.User.Identity as User;
this._announcement.Title = this.txtTitle.Text;
this._announcement.Content = this.txtContent.Text;
this._announcement.Section = base.Section;
//this._announcement.UpdateTimestamp = DateTime.Now;
this._announcement.ExpireDate = DateTime.Now.AddDays(5);
try
{
// Only save meta data.
this._module.SaveAnnouncement(this._announcement);
Context.Response.Redirect("EditAnnouncements.aspx" + base.GetBaseQueryString());
}
catch (Exception ex)
{
ShowError("Error saving file: " + ex.Message);
}
}
}
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
this._module.DeleteAnnouncements(this._announcement);
Context.Response.Redirect("EditAnnouncements.aspx" + base.GetBaseQueryString());
}
catch (Exception ex)
{
ShowError("Error deleting Announcements: " + ex.Message);
}
}
protected void btnCancel_Click(object sender, EventArgs e)
{
Context.Response.Redirect("EditAnnouncements.aspx" + base.GetBaseQueryString());
}
}
}
到此就完成了公告模块的开发 在后台页面将模块添加到前台页面就可以显示了.
可以改进的地方:
为模块添加url重写,在后台管理页面设置参数.Created by jecray