(ASP.NET) ASP.NET (2009 год)

Этюды на ASP2. Делаем RSS-канал на одной SQL-процедуре.

Я давно и с удовольствием пользуюсь RSS-каналами. Как настроить чтение с них и как ими пользоваться я описал в разделе Мой выбор - Firefox. Ровно так же строятся и все остальные ленты, например YRL.

Вообще-то RSS удобно пользоваться для динамично меняющегося контента - типа форумов или новостей. Но в 2009-м году я сделал небольшой рефакторинг своему блогу-программиста и наряду с гостевой книгой, бегущей лентой и прочим я добавил в том числе RSS-каналы.

Я нашел в интернете много какого-то глючного и крученого софта для построения RSS, не сомневаюсь что и Билл Гейтс отметится на этом поприще тоже и выпустит какую-нибудь глюковатую софтину для построения RSS. Наверняка микрософт-пресс поглумится над нами - издав справочник на 1000 страниц, как строить RSS в их софтине, наверняка MS организует обучающие курсы по построению RSS в их софтине...

Поэтому на этой страничке я покажу, как построить RSS-канал на одной-единственной процедуре и крошечной обвязке вокруг нее - формирующей вызов этой процедуры по параметрам, заданным в интернете).


Итак, у меня есть таблица со входными страничками на мой блог vb-net.com:


   1:  CREATE TABLE [dbo].[Entrance](
   2:      [i] [int] IDENTITY(1,1) NOT NULL,
   3:      [ID] [uniqueidentifier] NOT NULL,
   4:      [CrDate] [smalldatetime] NOT NULL,
   5:      [Type] [nvarchar](50) NOT NULL,
   6:      [URL] [nvarchar](250) NOT NULL,
   7:      [TXT] [nvarchar](250) NOT NULL,
   8:      [Descr] [nvarchar](1000) NULL
   9:  ) ON [PRIMARY]

Она заполнена примерно такими данными:




Для формирования RSS-канала нужна одна-единственная SQL-процедура. В моем случае она выдает RSS-канал по переданному параметры - новости SQL или, например новости MONO.

   1:  ALTER procedure GetRSS
   2:  @Type nvarchar(10)
   3:  as
   4:   
   5:  CREATE TABLE [dbo].[#X1](
   6:      [i] [int] IDENTITY(1,1) NOT NULL,
   7:      [TXT] [nvarchar](max) NULL
   8:  ) ON [PRIMARY]
   9:   
  10:  insert #X1
  11:  select
  12:  '     <item>' + char(13) + char(10) +
  13:  '       <title>' + 
  14:  @Type + ': ' + TXT +
  15:  '</title>' + char(13) + char(10) + 
  16:  '       <link>'  + 
  17:  URL  + 
  18:  '</link>'  + char(13) + char(10) +
  19:  '       <guid>' +
  20:  '//forum.vb-net.com/Forum.aspx?id='+cast(ID as nvarchar(36)) + 
  21:  '</guid>' + char(13) + char(10) +
  22:  '       <pubDate>' +
  23:  cast (CrDate as nvarchar)+
  24:  '</pubDate>'  + char(13) + char(10) +
  25:  '       <description>' +
  26:  isnull(Descr,'') +
  27:  '</description>'  + char(13) + char(10) +
  28:  '     </item>'  + char(13) + char(10) 
  29:  as RSS 
  30:  from Entrance
  31:  where Type like @Type+'%' 
  32:  order by type
  33:   
  34:   
  35:  select
  36:  '<?xml version="1.0"?>' + char(13) + char(10) +
  37:  '<rss version="2.0">' + char(13) + char(10) +
  38:  ' <channel>' + char(13) + char(10) +
  39:  '   <title>' + 'vb-net.com '+ @Type + ' News</title>' + char(13) + char(10) +
  40:  '   <link>//www.vb-net.com/</link>' + char(13) + char(10) +
  41:  '   <description>Блог программиста Еремина В.В.</description>' + char(13) + char(10) +
  42:  '   <language>ru-ru</language>' + char(13) + char(10) 
  43:  as RSS
  44:  UNION ALL
  45:   
  46:  Select TXT as RSS from #X1
  47:   
  48:  UNION ALL
  49:  select
  50:  ' </channel>' + char(13) + char(10) +
  51:  '</rss>' + char(13) + char(10) 
  52:  as RSS

Единственная причина, почему я сделал через временную таблу - я хотел просто просортировать новости - если вам это не надо, можно обойтись без временной таблы - это съэкономит ресурсы SQL.

Все что нам нужно еще - крошечная обвязка, чтобы проверить параметры и вызвать эту процедуру. На самом деле эту обвязку можно сделать и в пять строк, если вы не битесь досить свой SQL левыми запросами.


   1:  <%@ WebHandler Language="VB" Class="rss" %>
   2:   
   3:  Imports System
   4:  Imports System.Web
   5:   
   6:  Public Class rss : Implements IHttpHandler
   7:      
   8:      Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
   9:          
  10:   
  11:          Dim CN As System.Data.SqlClient.SqlConnection
  12:          Dim CMD As Data.SqlClient.SqlCommand
  13:          
  14:          If HttpContext.Current.Request.QueryString("Type") Is Nothing Then
  15:              context.Response.ContentType = "text/xml"
  16:              CN = New System.Data.SqlClient.SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("SQLServer_ConnectionStrings").ConnectionString)
  17:              CN.Open()
  18:              CMD = New Data.SqlClient.SqlCommand("[GetRSS]", CN)
  19:              CMD.CommandType = Data.CommandType.StoredProcedure
  20:              CMD.Parameters.AddWithValue("Type", "")
  21:          ElseIf HttpContext.Current.Request.QueryString("Type") = "" Then
  22:              context.Response.ContentType = "text/xml"
  23:              CN = New System.Data.SqlClient.SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("SQLServer_ConnectionStrings").ConnectionString)
  24:              CN.Open()
  25:              CMD = New Data.SqlClient.SqlCommand("[GetRSS]", CN)
  26:              CMD.CommandType = Data.CommandType.StoredProcedure
  27:              CMD.Parameters.AddWithValue("Type", "")
  28:              context.Response.ContentType = "text/xml"
  29:          ElseIf HttpContext.Current.Request.QueryString("Type") = "MONO" Or _
  30:              HttpContext.Current.Request.QueryString("Type") = "ASP.NET" Or _
  31:              HttpContext.Current.Request.QueryString("Type") = "NET" Or _
  32:              HttpContext.Current.Request.QueryString("Type") = "SOFT" Or _
  33:              HttpContext.Current.Request.QueryString("Type") = "SQL" Or _
  34:              HttpContext.Current.Request.QueryString("Type") = "UNIX" Or _
  35:              HttpContext.Current.Request.QueryString("Type") = "Social" Or _
  36:              HttpContext.Current.Request.QueryString("Type") = "Notes" Then
  37:              CN = New System.Data.SqlClient.SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("SQLServer_ConnectionStrings").ConnectionString)
  38:              CN.Open()
  39:              CMD = New Data.SqlClient.SqlCommand("[GetRSS]", CN)
  40:              CMD.CommandType = Data.CommandType.StoredProcedure
  41:              CMD.Parameters.AddWithValue("Type", HttpContext.Current.Request.QueryString("Type"))
  42:          Else
  43:              context.Response.ContentType = "text/plain"
  44:              context.Response.Write("Bad request. Use Type=MONO,ASP.NET,NET,SOFT,SQL,UNIX,Notes,Social or blank")
  45:              Exit Sub
  46:          End If
  47:          '
  48:          Dim RDR As Data.SqlClient.SqlDataReader = CMD.ExecuteReader
  49:          While RDR.Read
  50:              context.Response.Write(RDR("RSS"))
  51:          End While
  52:          CN.Close()
  53:        
  54:      End Sub
  55:   
  56:      Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
  57:          Get
  58:              Return False
  59:          End Get
  60:      End Property
  61:   
  62:  End Class

И, наконец, в титуле этого сайта лежит следующее:


   1:  <link rel="alternate" type="application/rss+xml" title="vb-net.com ALL news" href="//forum.vb-net.com/rss.ashx" />
   2:  <link rel="alternate" type="application/rss+xml" title="vb-net.com SOFT news" href="//forum.vb-net.com/rss.ashx?type=SOFT" />
   3:  <link rel="alternate" type="application/rss+xml" title="vb-net.com MONO news" href="//forum.vb-net.com/rss.ashx?type=MONO" />
   4:  <link rel="alternate" type="application/rss+xml" title="vb-net.com ASP.NET news" href="//forum.vb-net.com/rss.ashx?type=ASP.NET" />
   5:  <link rel="alternate" type="application/rss+xml" title="vb-net.com NET news" href="//forum.vb-net.com/rss.ashx?type=NET" />
   6:  <link rel="alternate" type="application/rss+xml" title="vb-net.com SQL news" href="//forum.vb-net.com/rss.ashx?type=SQL" />
   7:  <link rel="alternate" type="application/rss+xml" title="vb-net.com UNIX news" href="//forum.vb-net.com/rss.ashx?type=UNIX" />
   8:  <link rel="alternate" type="application/rss+xml" title="vb-net.com Notes news" href="//forum.vb-net.com/rss.ashx?type=Notes" />
   9:  <link rel="alternate" type="application/rss+xml" title="vb-net.com Social news" href="//forum.vb-net.com/rss.ashx?type=Social" />

Вот собственно и все. И еще пять строчек ушло на формирование бегущей строки. В ней новости, напротив, намеренно перемешаны.

Если же вас интересует как сделать такой же RSS-channel на полностью бесплатной и переносимой платформе MONO, то вы можете посмотреть на эту же технику в СУБД PostgreSQL - Экспорт данных из PostgeSQL в XML.



Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19>  <20>  <21>  <22>  <23
Link to this page: //www.vb-net.com/rss/index.htm
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <CHAT ME>  <ABOUT ME>  < THANKS ME>