本程序参考了《ASP.NET Ajax程序设计—第I卷》“9.4 DynamicPopulate:“穷人的”UpdatePanel” 里面的一些框架
下面是我的代码清单:
MySelf/RssNews.aspx | 前台页面 |
MySelf/RssNews.css | 样式表 |
MySelf/NewsService.asmx | 用于内容显示的Web Service |
Images/ajax-loader.gif | 异步刷新时的图标 |
App_Code/NewsData.dbml | 新闻数据的实体类 |
App_Code/NewsDataService.vb | 数据提供器 |
App_Code/NewsService.vb | Web Service的后端文件 |
主要内容:
App_Code/NewsData.dbml:
App_Code/NewsDataService.vb:
Imports
Microsoft.VisualBasic
Imports System.Collections.Generic
Imports System.Xml
Imports System.Net
Public Class NewsDataService Class NewsDataService
''' <summary>
''' 存放数据的静态对象
''' </summary>
''' <remarks></remarks>
Shared m_data As List(Of NewsEntry)
''' <summary>
''' 用于存放RSSFeedUrl
''' </summary>
''' <remarks></remarks>
Private Const feedUrl As String = "http://blog.csdn.net/lishewen/Rss.aspx"
''' <summary>
''' 获取文章的简要列表
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function GetNewsList()Function GetNewsList() As List(Of NewsEntryLight)
If m_data Is Nothing Then
initData()
End If
Return m_data.ConvertAll(Of NewsEntryLight)(AddressOf NewsEntryToNewsEntryLight)
End Function
''' <summary>
''' 实现一个从NewsEntry到NewsEntryLight的Converter
''' </summary>
''' <param name="NE"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Shared Function NewsEntryToNewsEntryLight()Function NewsEntryToNewsEntryLight(ByVal NE As NewsEntry) As NewsEntryLight
Return NE
End Function
''' <summary>
''' 从Rss源里获取数据初始化
''' </summary>
''' <remarks></remarks>
Private Shared Sub initData()Sub initData()
m_data = New List(Of NewsEntry)
Dim rssReader As XmlTextReader = Nothing
Dim itemCount = 0
Try
Dim rssFeed = WebRequest.Create(feedUrl)
rssReader = New XmlTextReader(rssFeed.GetResponse.GetResponseStream)
While rssReader.Read
If rssReader.IsStartElement And rssReader.LocalName = "item" Then
Dim itemReader As XmlReader = Nothing
Try
Dim NewsItem As New NewsEntry
NewsItem.ID = itemCount
NewsItem.Views = 0
itemReader = rssReader.ReadSubtree
While itemReader.Read
If itemReader.IsStartElement Then
Select Case itemReader.LocalName
Case "title"
NewsItem.Title = itemReader.ReadString
Case "pubDate"
NewsItem.PostDate = Date.Parse(itemReader.ReadString)
Case "description"
NewsItem.Content = itemReader.ReadString
Case "creator"
NewsItem.Author = itemReader.ReadString
End Select
End If
End While
m_data.Add(NewsItem)
itemCount += 1
Catch ex As Exception
Finally
If Not itemReader Is Nothing Then
itemReader.Close()
End If
End Try
End If
'获取新闻数为10条记录
If itemCount >= 10 Then
Exit While
End If
End While
Catch ex As Exception
Finally
If Not rssReader Is Nothing Then
rssReader.Close()
End If
End Try
End Sub
''' <summary>
''' 获得新闻的详细数据
''' </summary>
''' <param name="id">新闻ID</param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function GetNewsDetail()Function GetNewsDetail(ByVal id As Integer) As NewsEntry
If m_data Is Nothing Then
initData()
End If
'用VB9新增的XX表达式来筛选数据
Dim news = From NewsItem In m_data Where NewsItem.ID = id Select NewsItem
news(0).Views += 1
Return news(0)
End Function
End Class
Imports System.Collections.Generic
Imports System.Xml
Imports System.Net
Public Class NewsDataService Class NewsDataService
''' <summary>
''' 存放数据的静态对象
''' </summary>
''' <remarks></remarks>
Shared m_data As List(Of NewsEntry)
''' <summary>
''' 用于存放RSSFeedUrl
''' </summary>
''' <remarks></remarks>
Private Const feedUrl As String = "http://blog.csdn.net/lishewen/Rss.aspx"
''' <summary>
''' 获取文章的简要列表
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function GetNewsList()Function GetNewsList() As List(Of NewsEntryLight)
If m_data Is Nothing Then
initData()
End If
Return m_data.ConvertAll(Of NewsEntryLight)(AddressOf NewsEntryToNewsEntryLight)
End Function
''' <summary>
''' 实现一个从NewsEntry到NewsEntryLight的Converter
''' </summary>
''' <param name="NE"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Shared Function NewsEntryToNewsEntryLight()Function NewsEntryToNewsEntryLight(ByVal NE As NewsEntry) As NewsEntryLight
Return NE
End Function
''' <summary>
''' 从Rss源里获取数据初始化
''' </summary>
''' <remarks></remarks>
Private Shared Sub initData()Sub initData()
m_data = New List(Of NewsEntry)
Dim rssReader As XmlTextReader = Nothing
Dim itemCount = 0
Try
Dim rssFeed = WebRequest.Create(feedUrl)
rssReader = New XmlTextReader(rssFeed.GetResponse.GetResponseStream)
While rssReader.Read
If rssReader.IsStartElement And rssReader.LocalName = "item" Then
Dim itemReader As XmlReader = Nothing
Try
Dim NewsItem As New NewsEntry
NewsItem.ID = itemCount
NewsItem.Views = 0
itemReader = rssReader.ReadSubtree
While itemReader.Read
If itemReader.IsStartElement Then
Select Case itemReader.LocalName
Case "title"
NewsItem.Title = itemReader.ReadString
Case "pubDate"
NewsItem.PostDate = Date.Parse(itemReader.ReadString)
Case "description"
NewsItem.Content = itemReader.ReadString
Case "creator"
NewsItem.Author = itemReader.ReadString
End Select
End If
End While
m_data.Add(NewsItem)
itemCount += 1
Catch ex As Exception
Finally
If Not itemReader Is Nothing Then
itemReader.Close()
End If
End Try
End If
'获取新闻数为10条记录
If itemCount >= 10 Then
Exit While
End If
End While
Catch ex As Exception
Finally
If Not rssReader Is Nothing Then
rssReader.Close()
End If
End Try
End Sub
''' <summary>
''' 获得新闻的详细数据
''' </summary>
''' <param name="id">新闻ID</param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function GetNewsDetail()Function GetNewsDetail(ByVal id As Integer) As NewsEntry
If m_data Is Nothing Then
initData()
End If
'用VB9新增的XX表达式来筛选数据
Dim news = From NewsItem In m_data Where NewsItem.ID = id Select NewsItem
news(0).Views += 1
Return news(0)
End Function
End Class
App_Code/NewsService.vb:
Imports
System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
< WebService( Namespace : = " http://www.lishewen.com/ " ) > _
< WebServiceBinding(ConformsTo: = WsiProfiles.BasicProfile1_1) > _
< Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated() > _
< Script.Services.ScriptService() > _
Public Class NewsService
Inherits System.Web.Services.WebService
' '' <summary>
' '' 获取新闻详细信息的HTML
' '' </summary>
' '' <param name="contextKey"></param>
' '' <returns></returns>
' '' <remarks></remarks>
< WebMethod() > _
Public Function GetNewsDetailsHTMLString( ByVal contextKey As String ) As String
Dim newsId As Integer
If Not Integer .TryParse(contextKey, newsId) Then
Return String .Empty
End If
Dim news = NewsDataService.GetNewsDetail(newsId)
Dim newsHTMLBuilder As New System.Text.StringBuilder
newsHTMLBuilder.AppendFormat( " <div style='text-align:center;'>posted by {0} at {1},{2} views</div> " , news.Author, news.PostDate.ToShortDateString, news.Views)
newsHTMLBuilder.AppendFormat( " <div>{0}</div> " , news.Content)
Return newsHTMLBuilder.ToString
End Function
End Class
Imports System.Web.Services
Imports System.Web.Services.Protocols
< WebService( Namespace : = " http://www.lishewen.com/ " ) > _
< WebServiceBinding(ConformsTo: = WsiProfiles.BasicProfile1_1) > _
< Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated() > _
< Script.Services.ScriptService() > _
Public Class NewsService
Inherits System.Web.Services.WebService
' '' <summary>
' '' 获取新闻详细信息的HTML
' '' </summary>
' '' <param name="contextKey"></param>
' '' <returns></returns>
' '' <remarks></remarks>
< WebMethod() > _
Public Function GetNewsDetailsHTMLString( ByVal contextKey As String ) As String
Dim newsId As Integer
If Not Integer .TryParse(contextKey, newsId) Then
Return String .Empty
End If
Dim news = NewsDataService.GetNewsDetail(newsId)
Dim newsHTMLBuilder As New System.Text.StringBuilder
newsHTMLBuilder.AppendFormat( " <div style='text-align:center;'>posted by {0} at {1},{2} views</div> " , news.Author, news.PostDate.ToShortDateString, news.Views)
newsHTMLBuilder.AppendFormat( " <div>{0}</div> " , news.Content)
Return newsHTMLBuilder.ToString
End Function
End Class
MySelf/RssNews.css:
body
{...}
{
}
.updating
{...} {
background-image:url('../Images/ajax-loader.gif');
background-repeat:no-repeat;
padding:2px;
height:2em;
margin:5px;
}
}
.updating
{...} {
background-image:url('../Images/ajax-loader.gif');
background-repeat:no-repeat;
padding:2px;
height:2em;
margin:5px;
}
MySelf/RssNews.aspx:
<
%@ Page
Language
="VB"
AutoEventWireup
="false"
CodeFile
="RssNews.aspx.vb"
Inherits
="MySelf_RssNews"
%
>
<! 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 > Untitled Page </ title >
< link href ="RssNews.css" rel ="stylesheet" type ="text/css" />
< script type ="text/javascript" >
function pageLoad() {
}
</ script >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< asp:ScriptManager ID ="ScriptManager1" runat ="server" />
< asp:ObjectDataSource ID ="NewsDataSource" runat ="server" SelectMethod ="GetNewsList"
TypeName ="NewsDataService" ></ asp:ObjectDataSource >
< asp:GridView ID ="GridView1" runat ="server" AutoGenerateColumns ="False" DataSourceID ="NewsDataSource"
ShowHeader ="False" >
< Columns >
< asp:TemplateField >
< ItemTemplate >
< a name ='<%# Eval("ID","name{0}") % > '> </ a >
< asp:HyperLink ID ="hlMore" runat ="server" NavigateUrl ='<%# Eval("ID", "#name{0}") % > '>more... </ asp:HyperLink >
< asp:Label ID ="lbTitle" runat ="server" Font-Bold ="True" Text ='<%# Bind("Title") % > '> </ asp:Label >
< asp:Panel ID ="newsDetails" runat ="server" >
</ asp:Panel >
< asp:DynamicPopulateExtender ID ="DynamicPopulateExtender1" runat ="server" ContextKey ='<%# Eval("ID") % > '
Enabled="True" PopulateTriggerControlID="hlMore" TargetControlID="newsDetails"
UpdatingCssClass="updating" ServicePath="~/MySelf/NewsService.asmx" ServiceMethod="GetNewsDetailsHTMLString">
</ asp:DynamicPopulateExtender >
</ ItemTemplate >
< ItemStyle CssClass ="gridRow" />
</ asp:TemplateField >
</ Columns >
</ asp:GridView >
</ div >
</ form >
</ body >
</ html >
<! 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 > Untitled Page </ title >
< link href ="RssNews.css" rel ="stylesheet" type ="text/css" />
< script type ="text/javascript" >
function pageLoad() {
}
</ script >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< asp:ScriptManager ID ="ScriptManager1" runat ="server" />
< asp:ObjectDataSource ID ="NewsDataSource" runat ="server" SelectMethod ="GetNewsList"
TypeName ="NewsDataService" ></ asp:ObjectDataSource >
< asp:GridView ID ="GridView1" runat ="server" AutoGenerateColumns ="False" DataSourceID ="NewsDataSource"
ShowHeader ="False" >
< Columns >
< asp:TemplateField >
< ItemTemplate >
< a name ='<%# Eval("ID","name{0}") % > '> </ a >
< asp:HyperLink ID ="hlMore" runat ="server" NavigateUrl ='<%# Eval("ID", "#name{0}") % > '>more... </ asp:HyperLink >
< asp:Label ID ="lbTitle" runat ="server" Font-Bold ="True" Text ='<%# Bind("Title") % > '> </ asp:Label >
< asp:Panel ID ="newsDetails" runat ="server" >
</ asp:Panel >
< asp:DynamicPopulateExtender ID ="DynamicPopulateExtender1" runat ="server" ContextKey ='<%# Eval("ID") % > '
Enabled="True" PopulateTriggerControlID="hlMore" TargetControlID="newsDetails"
UpdatingCssClass="updating" ServicePath="~/MySelf/NewsService.asmx" ServiceMethod="GetNewsDetailsHTMLString">
</ asp:DynamicPopulateExtender >
</ ItemTemplate >
< ItemStyle CssClass ="gridRow" />
</ asp:TemplateField >
</ Columns >
</ asp:GridView >
</ div >
</ form >
</ body >
</ html >