portal學習--模板及模塊的製作
1.所有的模板都繼承自PortalModuleControl(移動設備則繼承自MobileModuleControl),為了網站速度,還定義一個類CachedPortalModuleControl(繼承自Control),它們一並放在Components/DesktopControls.cs文件裡.其中PortalModuleControl的源代碼如下,至於CachedPortalModuleControl的代碼就不列出來了:
/// 門戶站點用戶控件基類
/// </summary>
public class PortalModuleControl : UserControl
{
// 私有變量
private ModuleSettings _moduleConfiguration; // 模塊設置信息
private int _isEditable = 0 ; //
private int _portalId = 0 ; // 所屬門戶站點Id
private Hashtable _settings; //
#region 公共屬性
// Public property accessors
/// <summary>
/// 模塊Id
/// </summary>
[Browsable( false ),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int ModuleId
{
get
{
return ( int ) _moduleConfiguration.ModuleId;
}
}
/// <summary>
/// 所屬門戶站點Id
/// </summary>
[Browsable( false ),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int PortalId
{
get
{
return _portalId;
}
set
{
_portalId = value;
}
}
/// <summary>
/// 模塊是否處於編輯模式的標記屬性(true:可編輯/false:不可編輯)
/// </summary>
[Browsable( false ),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsEditable
{
get
{
// Perform tri-state switch check to avoid having to perform a security
// role lookup on every property access (instead caching the result)
if (_isEditable == 0 )
{
// Obtain PortalSettings from Current Context
PortalSettings portalSettings = (PortalSettings)
HttpContext.Current.Items[ " PortalSettings " ];
if (portalSettings.AlwaysShowEditButton == true ||
PortalSecurity.IsInRoles(_moduleConfiguration.AuthorizedEditRoles))
{
_isEditable = 1 ;
}
else
{
_isEditable = 2 ;
}
}
return (_isEditable == 1 );
}
}
/// <summary>
/// 模塊設置信息
/// </summary>
[Browsable( false ),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ModuleSettings ModuleConfiguration
{
get
{
return _moduleConfiguration;
}
set
{
_moduleConfiguration = value;
}
}
/// <summary>
/// 獲取指定用戶模塊的設置信息(為XML/XSL模板和圖片模板時設置XML/XSL文件和圖片的地址)
/// </summary>
[Browsable( false ),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Hashtable Settings
{
get
{
if (_settings == null )
{
_settings = Configuration.GetModuleSettings(ModuleId);
}
return _settings;
}
}
#endregion
}
2.下面以Announcements.ascx為例,講一下模板的實現.
通告模板使用了一個表,用來存儲通告的內容,該表的結構如下:
名稱 | 型別 | 長度 | 空 |
ItemID | int | 4 | |
ModuleID | int | 4 | |
CreatedByUser | nvarchar | 100 | null |
CreatedDate | datetime | 8 | null |
Title | nvarchar | 150 | null |
MoreLink | nvarchar | 150 | null |
MobileMoreLink | nvarchar | 150 | null |
ExpireDate | datetime | 8 | null |
Description | nvarchar | 2000 | null |
3.為了操作這個表,我們定義了一類,它用於查找全部的通告,查找單個通告,以及添加,刪除,更新通告,它們分別調用了相應的存儲過程.
{
public DataSet GetAnnouncements( int moduleId)
{
// Create Instance of Connection and Command Object
SqlConnection myConnection = new
SqlConnection(ConfigurationSettings.AppSettings[ " connectionString " ]);
SqlDataAdapter myCommand = new SqlDataAdapter( " Portal_GetAnnouncements " , myConnection);
// Mark the Command as a SPROC
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
// Add Parameters to SPROC
SqlParameter parameterModuleId = new SqlParameter( " @ModuleID " , SqlDbType.Int, 4 );
parameterModuleId.Value = moduleId;
myCommand.SelectCommand.Parameters.Add(parameterModuleId);
// Create and Fill the DataSet
DataSet myDataSet = new DataSet();
myCommand.Fill(myDataSet);
// Return the DataSet
return myDataSet;
}
public SqlDataReader GetSingleAnnouncement( int itemId)
{
// Create Instance of Connection and Command Object
SqlConnection myConnection = new
SqlConnection(ConfigurationSettings.AppSettings[ " connectionString " ]);
SqlCommand myCommand = new SqlCommand( " Portal_GetSingleAnnouncement " , myConnection);
// Mark the Command as a SPROC
myCommand.CommandType = CommandType.StoredProcedure;
// Add Parameters to SPROC
SqlParameter parameterItemId = new SqlParameter( " @ItemID " , SqlDbType.Int, 4 );
parameterItemId.Value = itemId;
myCommand.Parameters.Add(parameterItemId);
// Execute the command
myConnection.Open();
SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
// Return the datareader
return result;
}
/// <summary>
/// 刪除公告
/// </summary>
/// <param name="itemID"></param>
public void DeleteAnnouncement( int itemID)
{
// Create Instance of Connection and Command Object
SqlConnection myConnection = new
SqlConnection(ConfigurationSettings.AppSettings[ " connectionString " ]);
SqlCommand myCommand = new SqlCommand( " Portal_DeleteAnnouncement " , myConnection);
// Mark the Command as a SPROC
myCommand.CommandType = CommandType.StoredProcedure;
// Add Parameters to SPROC
SqlParameter parameterItemID = new SqlParameter( " @ItemID " , SqlDbType.Int, 4 );
parameterItemID.Value = itemID;
myCommand.Parameters.Add(parameterItemID);
myConnection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}
/// <summary>
/// 添加新公告
/// </summary>
/// <param name="moduleId"></param>
/// <param name="itemId"></param>
/// <param name="userName"></param>
/// <param name="title"></param>
/// <param name="expireDate"></param>
/// <param name="description"></param>
/// <param name="moreLink"></param>
/// <param name="mobileMoreLink"></param>
/// <returns></returns>
public int AddAnnouncement( int moduleId, int itemId, String userName, String title, DateTime expireDate,
String description, String moreLink, String mobileMoreLink)
{
if (userName.Length < 1 )
{
userName = " unknown " ;
}
// Create Instance of Connection and Command Object
SqlConnection myConnection = new
SqlConnection(ConfigurationSettings.AppSettings[ " connectionString " ]);
SqlCommand myCommand = new SqlCommand( " Portal_AddAnnouncement " , myConnection);
// Mark the Command as a SPROC
myCommand.CommandType = CommandType.StoredProcedure;
// Add Parameters to SPROC
SqlParameter parameterItemID = new SqlParameter( " @ItemID " , SqlDbType.Int, 4 );
parameterItemID.Direction = ParameterDirection.Output;
myCommand.Parameters.Add(parameterItemID);
SqlParameter parameterModuleID = new SqlParameter( " @ModuleID " , SqlDbType.Int, 4 );
parameterModuleID.Value = moduleId;
myCommand.Parameters.Add(parameterModuleID);
SqlParameter parameterUserName = new SqlParameter( " @UserName " , SqlDbType.NVarChar, 100 );
parameterUserName.Value = userName;
myCommand.Parameters.Add(parameterUserName);
SqlParameter parameterTitle = new SqlParameter( " @Title " , SqlDbType.NVarChar, 150 );
parameterTitle.Value = title;
myCommand.Parameters.Add(parameterTitle);
SqlParameter parameterMoreLink = new SqlParameter( " @MoreLink " , SqlDbType.NVarChar, 150 );
parameterMoreLink.Value = moreLink;
myCommand.Parameters.Add(parameterMoreLink);
SqlParameter parameterMobileMoreLink = new SqlParameter( " @MobileMoreLink " , SqlDbType.NVarChar, 150 );
parameterMobileMoreLink.Value = mobileMoreLink;
myCommand.Parameters.Add(parameterMobileMoreLink);
SqlParameter parameterExpireDate = new SqlParameter( " @ExpireDate " , SqlDbType.DateTime, 8 );
parameterExpireDate.Value = expireDate;
myCommand.Parameters.Add(parameterExpireDate);
SqlParameter parameterDescription = new SqlParameter( " @Description " , SqlDbType.NVarChar, 2000 );
parameterDescription.Value = description;
myCommand.Parameters.Add(parameterDescription);
myConnection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
return ( int )parameterItemID.Value;
}
/// <summary>
/// 更新公告
/// </summary>
/// <param name="moduleId"></param>
/// <param name="itemId"></param>
/// <param name="userName"></param>
/// <param name="title"></param>
/// <param name="expireDate"></param>
/// <param name="description"></param>
/// <param name="moreLink"></param>
/// <param name="mobileMoreLink"></param>
public void UpdateAnnouncement( int moduleId, int itemId, String userName, String title, DateTime expireDate,
String description, String moreLink, String mobileMoreLink)
{
if (userName.Length < 1 ) userName = " unknown " ;
// Create Instance of Connection and Command Object
SqlConnection myConnection = new
SqlConnection(ConfigurationSettings.AppSettings[ " connectionString " ]);
SqlCommand myCommand = new SqlCommand( " Portal_UpdateAnnouncement " , myConnection);
// Mark the Command as a SPROC
myCommand.CommandType = CommandType.StoredProcedure;
// Add Parameters to SPROC
SqlParameter parameterItemID = new SqlParameter( " @ItemID " , SqlDbType.Int, 4 );
parameterItemID.Value = itemId;
myCommand.Parameters.Add(parameterItemID);
SqlParameter parameterUserName = new SqlParameter( " @UserName " , SqlDbType.NVarChar, 100 );
parameterUserName.Value = userName;
myCommand.Parameters.Add(parameterUserName);
SqlParameter parameterTitle = new SqlParameter( " @Title " , SqlDbType.NVarChar, 150 );
parameterTitle.Value = title;
myCommand.Parameters.Add(parameterTitle);
SqlParameter parameterMoreLink = new SqlParameter( " @MoreLink " , SqlDbType.NVarChar, 150 );
parameterMoreLink.Value = moreLink;
myCommand.Parameters.Add(parameterMoreLink);
SqlParameter parameterMobileMoreLink = new SqlParameter( " @MobileMoreLink " , SqlDbType.NVarChar, 150 );
parameterMobileMoreLink.Value = mobileMoreLink;
myCommand.Parameters.Add(parameterMobileMoreLink);
SqlParameter parameterExpireDate = new SqlParameter( " @ExpireDate " , SqlDbType.DateTime, 8 );
parameterExpireDate.Value = expireDate;
myCommand.Parameters.Add(parameterExpireDate);
SqlParameter parameterDescription = new SqlParameter( " @Description " , SqlDbType.NVarChar, 2000 );
parameterDescription.Value = description;
myCommand.Parameters.Add(parameterDescription);
myConnection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}
}
4.開始編輯這個模板的頁面了,通告模板使用一個DataList來顯示數據,新增和修改都是通過其它頁面,這裡只給了每個功能一個鏈接.別急,每個模塊都得有個標題,為了通用,所以也做成了一個用戶控件DesktopModuleTitle.ascx.標題還有模塊的其它一些屬性(如可編輯角色等)也可能要修改,所以在控件裡還放了個LinkButton用來鏈接到修改頁面Admin/ModuleSettings.aspx.
其網頁的全部代碼如下,是全部代碼嗎?對,沒錯:
<% @ Control Language = " c# " AutoEventWireup = " false " Codebehind = " Announcements.ascx.cs " Inherits = " Portal.Web.Announcements " TargetSchema = " http://schemas.microsoft.com/intellisense/ie5 " %>
<!-- 新增公告鏈接,在這裡改鏈接的名稱和地址,還有是否開新窗口 -->
< ASPNETPortal:title EditText ="添加新公告" EditUrl ="~/DesktopModules/EditAnnouncements.aspx" runat ="server"
id ="Title1" />
< asp:DataList id ="myDataList" CellPadding ="4" Width ="98%" EnableViewState ="false" runat ="server" >
< ItemTemplate >
<!-- 修改公告鏈接 -->
< asp:HyperLink id ="editLink" runat ="server" Visible ="<%# IsEditable %>" NavigateUrl ='<%# "~/DesktopModules/EditAnnouncements.aspx?ItemID =" + DataBinder.Eval(Container.DataItem," ItemID") + "&mid =" + ModuleId %>' ImageUrl=" ~/images/edit.gif" >
</ asp:HyperLink >
<!-- 公告標題 -->
< SPAN class ="ItemTitle" > <% # DataBinder.Eval(Container.DataItem, " Title " ) %> </ SPAN >< BR >
<!-- 公告內容,這裡給了一個"更多"鏈接,用於查看詳細內容 -->
< SPAN class ="Normal" >
<% # DataBinder.Eval(Container.DataItem, " Description " ) %>
< asp:HyperLink id ="moreLink" runat ="server" Visible ='<%# DataBinder.Eval(Container.DataItem,"MoreLink") ! = String.Empty % > ' NavigateUrl=' <% # DataBinder.Eval(Container.DataItem, " MoreLink " ) %> '>更多... </ asp:HyperLink ></ SPAN >< BR >
</ ItemTemplate >
</ asp:DataList >
後台代碼其實沒什麼說的,太簡單了:
private void Page_Load( object sender, System.EventArgs e)
{
// Obtain announcement information from Announcements table
// and bind to the datalist control
AnnouncementsDB announcements = new AnnouncementsDB();
// DataBind Announcements to DataList Control
// 通過ModuleId獲取數據,所以相同模板的模塊,它們的數據會不同.
myDataList.DataSource = announcements.GetAnnouncements(ModuleId);
myDataList.DataBind();
}
好了,接下來再看看編輯單條通告的頁面是什麼樣的吧,煩,不說了.
5.前期工作終於做完了,開始調用這個模板啦,首先總要告訴系統這個模板的文件位置吧,在系統中用了一個頁面ModuleDefinitions.aspx來做維護,但其實原理還是在PortalCfg.xml中加上一條記錄,ModuleDefId是自動產生的(這裡ModuleDefId="1"),其它幾個都要自已定義.
<ModuleDefinition FriendlyName="公告" MobileSourceFile="MobileModules/Announcements.ascx" DesktopSourceFile="DesktopModules/Announcements.ascx" ModuleDefId="1" />
接下來就要根據這個模板新增模塊了,也做了一個維護頁面TabLayout.aspx,其實也還是在操作這個PortalCfg.xml文件,看到ModuleDefId的定義了嗎?如果ModuleDefId="1",那麼它就是用我們剛才建立的那個通告模板生成的,"新闻和特点" 就是了.想刪除嗎?也在這個頁面了.什麼,還想修改?前面說了,在Admin/ModuleSettings.aspx頁面修改吧.
<Tab TabId="1" TabName="主页" AccessRoles="All Users;" TabOrder="1" ShowMobile="true" MobileTabName="Home">
<Module ModuleId="1" ModuleTitle="快速链接" EditRoles="Admins;" ModuleDefId="8" PaneName="LeftPane" CacheTimeout="0" ModuleOrder="1" ShowMobile="false" />
<Module ModuleId="2" ModuleTitle="欢迎来到 Portal Starter Kit" EditRoles="Admins;" ModuleDefId="5" PaneName="ContentPane" CacheTimeout="0" ModuleOrder="1" ShowMobile="true" />
<Module ModuleId="3" ModuleTitle="新闻和特点" EditRoles="Admins;" ModuleDefId="1" PaneName="ContentPane" CacheTimeout="0" ModuleOrder="2" ShowMobile="true" />
<Module ModuleId="4" ModuleTitle="近期事件" EditRoles="Admins;" ModuleDefId="4" PaneName="ContentPane" CacheTimeout="0" ModuleOrder="3" ShowMobile="true" />
<Module ModuleId="5" ModuleTitle="本周要闻" EditRoles="Admins;" ModuleDefId="5" PaneName="RightPane" CacheTimeout="0" ModuleOrder="1" ShowMobile="false" />
<Module ModuleId="6" ModuleTitle="最佳Mover" EditRoles="Admins;" ModuleDefId="9" PaneName="RightPane" CacheTimeout="0" ModuleOrder="2" ShowMobile="false">
<Settings>
<Setting Name="xmlsrc">~/data/sales.xml</Setting>
<Setting Name="xslsrc">~/data/sales.xsl</Setting>
</Settings>
</Module>
</Tab>