在网上找到了一个叫做NewsArticles的dnn模块,作为文章管理还算不错,支持一级分类、用户投稿、权限控制、搜索等等,尤其是page的概念很不错,就是可以把一整篇文章分为几个小标题发表,每个标题内容作为一页,导航方式很人性化。不过美中不足的是没有提供分页功能,于是师域把这个光荣的任务交给了我,我也只好免为其难了。
NewsArticles的列表是通过用户控件ucListing.ascx实现的,我们要作的工作就是在这个控件中加入分页功能。分析源码发现:通过Repeater实现列表,数据使用了datareader读取。我写了一些代码,调试通过,但是运行的时候模块出错,信息如下:
Error loading module
DotNetNuke.ModuleLoadException: Unhandled Error Adding Module to ContentPane ---> System.Web.HttpException: Parser Error: External component has thrown an exception. ---> System.Web.HttpException: External component has thrown an exception. ---> System.Web.HttpCompileException: External component has thrown an exception. at System.Web.Compilation.BaseCompiler.ThrowIfCompilerErrors(CompilerResults results, CodeDomProvider codeProvider, CodeCompileUnit sourceData, String sourceFile, String sourceString) at System.Web.Compilation.BaseCompiler.GetCompiledType() at System.Web.UI.UserControlParser.CompileIntoType() at System.Web.UI.TemplateParser.GetParserCacheItemThroughCompilation() --- End of inner exception stack trace --- at System.Web.UI.TemplateParser.GetParserCacheItemInternal(Boolean fCreateIfNotFound) at System.Web.UI.TemplateParser.GetParserCacheItemWithNewConfigPath() at System.Web.UI.TemplateControlParser.GetReferencedType(TemplateControlParser parser, String virtualPath) at System.Web.UI.TemplateControlParser.GetUserControlType(String virtualPath) at System.Web.UI.TemplateControlParser.ProcessDirective(String directiveName, IDictionary directive) at System.Web.UI.TemplateParser.ParseStringInternal(String text) at System.Web.UI.TemplateParser.ParseString(String text, String virtualPath, String basePhysicalDir) --- End of inner exception stack trace --- at System.Web.UI.TemplateParser.ParseString(String text, String virtualPath, String basePhysicalDir) at System.Web.UI.TemplateParser.ParseFile(String filename, String virtualPath) at System.Web.UI.TemplateParser.Parse() at System.Web.UI.TemplateParser.GetParserCacheItemThroughCompilation() at System.Web.UI.TemplateParser.GetParserCacheItemInternal(Boolean fCreateIfNotFound) at System.Web.UI.TemplateParser.GetParserCacheItemWithNewConfigPath() at System.Web.UI.TemplateParser.GetParserCacheItem() at System.Web.UI.TemplateControlParser.CompileAndGetParserCacheItem(String virtualPath, String inputFile, HttpContext context) at System.Web.UI.TemplateControlParser.GetCompiledType(String virtualPath, String inputFile, HttpContext context) at System.Web.UI.UserControlParser.GetCompiledUserControlType(String virtualPath, String inputFile, HttpContext context) at System.Web.UI.TemplateControl.LoadControl(String virtualPath) at DnnForge.NewsArticles.NewsArticles.LoadControlType() at DnnForge.NewsArticles.NewsArticles.Page_Init(Object sender, EventArgs e) at System.Web.UI.Control.OnInit(EventArgs e) at System.Web.UI.UserControl.OnInit(EventArgs e) at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Control.AddedControl(Control control, Int32 index) at System.Web.UI.ControlCollection.Add(Control child) at DotNetNuke.Skin.InjectModule(Control objPane, ModuleSettings ModuleSettings, PortalSettings PortalSettings) in G:\mywebs\DotNetNuke\admin\Skins\Skin.vb:line 600 --- End of inner exception stack trace ---
不知道原因出在哪里,希望大家指点一下,不胜感激。
ucListing.ascx源码:
<%@ Control language="vb" Inherits="DnnForge.NewsArticles.ucListing" CodeBehind="ucListing.ascx.vb" AutoEventWireup="false" Explicit="True" %>
<asp:Repeater ID="rptListing" Runat="server">
<ItemTemplate>

<asp:PlaceHolder ID="plhDayTop" Runat="server" Visible="False">
![]()
<table cellSpacing=1 cellPadding=3 width="100%" border=0>
<tr align=left>
![]()
</tr>
<tr>
![]()
</asp:PlaceHolder>
<table width="100%">
<tr>
<td><a href='<%# Page.ResolveUrl(NavigateUrl() & "&newsType=CategoryView&CategoryID=" & DataBinder.Eval(Container.DataItem, "CategoryID").ToString()) %>'><img src='<%# GetCategoryImage(DataBinder.Eval(Container.DataItem, "CategoryImage").ToString()) %>' border='0'></a></td>
![]()
<asp:HyperLink id="editLink" NavigateUrl='<%# GetEditUrl(DataBinder.Eval(Container.DataItem, "ArticleID").ToString()) %>' Visible="<%# IsEditable%>" runat="server"><asp:Image >
<a href='<%# Page.ResolveUrl(NavigateUrl() & "&newsType=ArticleView&articleId=" & DataBinder.Eval(Container.DataItem, "ArticleID").ToString()) %>' class="articleTitle"><%# DataBinder.Eval(Container.DataItem, "Title") %></a> <br>
By <%# DataBinder.Eval(Container.DataItem, "AuthorFirstName") %> <%# DataBinder.Eval(Container.DataItem, "AuthorLastName") %> (<%# DataBinder.Eval(Container.DataItem, "AuthorUserName") %>) @ <%# DataBinder.Eval(Container.DataItem, "CreatedDate", "{0:t}") %> :: <a href='<%# Page.ResolveUrl(NavigateUrl() & "&newsType=CategoryView&CategoryId=" & DataBinder.Eval(Container.DataItem, "CategoryID").ToString()) %>' class="CommandButton"><%# DataBinder.Eval(Container.DataItem, "CategoryName") %></a> :: <a href='<%# Page.ResolveUrl(NavigateUrl() & "&newsType=ArticleView&articleId=" & DataBinder.Eval(Container.DataItem, "ArticleID").ToString() & "#Comments") %>' class='CommandButton' ><%# DataBinder.Eval(Container.DataItem, "CommentCount") %> Comments</a> :: <%# DataBinder.Eval(Container.DataItem, "NumberOfViews") %> Views
</td>
</tr>
<tr>
<td colspan="3">
![]()
<table cellSpacing=1 cellPadding=3 width="100%" border=0>
<tr>
![]()
![]()
</td>
</tr>
<tr runat="server" visible="<%# IsMultiPage(Container.DataItem) %>">
![]()
</tr>
</table>
</TD></TR></TBODY></TABLE>
</td>
</tr>
</table>
<asp:PlaceHolder ID="plhSeperator" Runat="server" Visible="False"><hr></asp:PlaceHolder>
<asp:PlaceHolder ID="plhDayBottom" Runat="server" Visible="False">
</td>
</tr>
</table>
</TD></TR></TBODY></TABLE>
</asp:PlaceHolder>

</ItemTemplate>
</asp:Repeater>
<asp:label id="lblPageInfo2" runat="server" cssClass="TTTNormal"></asp:label>
<asp:datalist id="dlPager2" runat="server" repeatlayout="Flow" repeatdirection="Horizontal" cssclass="TTTNormal">
<selecteditemtemplate>
<asp:label id="Label2" CssClass="TTTNormalRed" runat="server">
<%# Ctype(Container.DataItem, PagerDetail).Text %>
</asp:label>
</selecteditemtemplate>
<itemtemplate>
<asp:hyperlink id="Hyperlink1" runat="server" navigateurl='<%# GetPagerURL(Container.DataItem) %>'>
<%# Ctype(Container.DataItem, PagerDetail).Text %>
</asp:hyperlink>
</itemtemplate>
</asp:datalist>
<asp:Label Runat="server" CssClass="NormalBold" ID="lblNoArticles" Visible="False"><br>No Articles Found.</asp:Label>
ucListing.ascx.vb源码:
Imports System.Web
Imports System.Web.UI.HtmlControls
Imports System.Web.UI.WebControls

Imports DotNetNuke

DnnForge.NewsArticles

ucListing

Inherits PortalModuleControl

Protected WithEvents rptListing As System.Web.UI.WebControls.Repeater

Private _articleList As ArrayList = Nothing
Private _lastCreatedDate As DateTime = Null.NullDate

Private _categoryID As Integer = Null.NullInteger
Private _maxCount As Integer = Null.NullInteger
Private _maxAge As Integer = Null.NullInteger
Private _showApprovedOnly As Boolean = True
Private _startDate As DateTime = DateTime.Now
Protected WithEvents lblNoArticles As System.Web.UI.WebControls.Label
Private _keywords As String = Null.NullString
Protected WithEvents lblPageInfo2 As System.Web.UI.WebControls.Label
Protected WithEvents dlPager2 As System.Web.UI.WebControls.DataList
Private _req As HttpRequest
Private _currentStrip As Integer
Private _stripCount As Integer
Private _startItem As Integer
Private _endItem As Integer
Private _pagerItems As New ArrayList


#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
InitializeComponent()

End Sub

.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()

End Sub

#End Region

.Load

If IsPostBack = False Then


End If

End Sub


PagerDetail

Public Text As String
Public Strip As Integer

End Class
![]()
' Beginning item of this page
Get
Return _startItem
End Get
End Property

![]()
' Ending item of this page
Get
Return _endItem
End Get
End Property

![]()
' Current page being viewed
Get
Return _currentStrip
End Get
End Property

![]()
' Count of pages existing in this folder
Get
Return _stripCount
End Get
End Property
BindListing()

Dim objArticleController As ArticleController = New ArticleController
Dim newPagerDetail As PagerDetail
Dim pagerCounter As Integer
' Grab current request context
_req = HttpContext.Current.Request

' Logic to determine paging
_currentStrip = CInt(_req("CurrentStrip"))

_articleList = objArticleController.GetArticleList(Me.ModuleId, CategoryID, MaxCount, MaxAge, ShowApprovedOnly, StartDate, Keywords)

Try

' Get the count of pages for this folder
_stripCount = CInt(10)

Catch ex As Exception
_stripCount = 1
End Try

' Do a little validation
If _currentStrip = 0 OrElse (_currentStrip > _stripCount) Then
_currentStrip = 1
End If

' Calculate the starting item
If _articleList.Count = 0 Then
_startItem = 0
Else
_startItem = (_currentStrip - 1) * _stripCount + 1
End If
' and calculate the ending item
_endItem = _startItem + _stripCount - 1
If _endItem > _articleList.Count Then
_endItem = _articleList.Count
End If

' Creates the pager items
' Create the previous item
If _stripCount > 1 AndAlso _currentStrip > 1 Then
newPagerDetail = New PagerDetail
newPagerDetail.Strip = _currentStrip - 1
newPagerDetail.Text = "Previous"
_pagerItems.Add(newPagerDetail)
End If

' Creates folder items
For pagerCounter = 1 To _stripCount
newPagerDetail = New PagerDetail
newPagerDetail.Strip = pagerCounter
newPagerDetail.Text = CStr(pagerCounter)
_pagerItems.Add(newPagerDetail)
Next

' Creates the next item
If _stripCount > 1 AndAlso _currentStrip < _stripCount Then
newPagerDetail = New PagerDetail
newPagerDetail.Strip = _currentStrip + 1
newPagerDetail.Text = "Next"
_pagerItems.Add(newPagerDetail)
End If

If (_articleList.Count = 0) Then
lblNoArticles.Visible = True
lblPageInfo2.Text = "Album contains nothing"
Else
dlPager2.DataSource = _articleList
If _currentStrip > 1 Then
dlPager2.SelectedIndex = _currentStrip
Else
dlPager2.SelectedIndex = 0
End If

dlPager2.DataBind()

lblPageInfo2.Text = "Page: "
rptListing.DataSource = _articleList
rptListing.DataBind()
lblNoArticles.Visible = False
End If

End Sub

![]()
Get
Return _categoryID
End Get
Set(ByVal Value As Integer)
_categoryID = Value
End Set
End Property

![]()
Get
Return _maxCount
End Get
Set(ByVal Value As Integer)
_maxCount = Value
End Set
End Property

![]()
Get
Return _maxAge
End Get
Set(ByVal Value As Integer)
_maxAge = Value
End Set
End Property

![]()
Get
Return _showApprovedOnly
End Get
Set(ByVal Value As Boolean)
_showApprovedOnly = Value
End Set
End Property

DateTime
Get
Return _startDate
End Get
Set(ByVal Value As DateTime)
_startDate = Value
End Set
End Property

![]()
Get
Return _keywords
End Get
Set(ByVal Value As String)
_keywords = Value
End Set
End Property


rptListing.ItemDataBound

If (e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem) Then

Dim currentArticle As ArticleInfo = CType(e.Item.DataItem, ArticleInfo)

If Not (currentArticle Is Nothing) Then

If (e.Item.ItemIndex = 0) Then

' Render Top
'
CType(e.Item.FindControl("plhDayTop"), PlaceHolder).Visible = True

Else

Dim previousArticle As ArticleInfo = CType(_articleList(e.Item.ItemIndex - 1), ArticleInfo)

If Not (currentArticle.CreatedDate.Day = previousArticle.CreatedDate.Day) Then

' Render Top
'
CType(e.Item.FindControl("plhDayTop"), PlaceHolder).Visible = True

End If

End If

If (e.Item.ItemIndex + 1 = _articleList.Count) Then

' Render Bottom
'
CType(e.Item.FindControl("plhDayBottom"), PlaceHolder).Visible = True

Else

Dim nextArticle As ArticleInfo = CType(_articleList(e.Item.ItemIndex + 1), ArticleInfo)

If Not (currentArticle.CreatedDate.Day = nextArticle.CreatedDate.Day) Then

' Render Bottom
'
CType(e.Item.FindControl("plhDayBottom"), PlaceHolder).Visible = True

Else

CType(e.Item.FindControl("plhSeperator"), PlaceHolder).Visible = True

End If

End If

End If

End If

End Sub

![]()

Return NavigateURL() & "&newsType=SubmitNews&articleID=" & articleID

End Function

![]()

Dim objArticle As ArticleInfo = CType(dataItem, ArticleInfo)

If (objArticle.PageCount > 0) Then

Return True

End If

Return False

End Function

![]()

If (image <> "") Then

Return Me.PortalSettings.UploadDirectory & image

Else

Return Page.ResolveUrl("~/images/spacer.gif")

End If

End Function

End Class

End Namespace