[WebMatrix 開發系列(1)] 撰寫自己的 RSSDataHelper 資料讀取器

在去年,其實筆者也有介紹過WebMatrx系列的開發,因為在開發資料庫應用程式時通常會使用OData Helper元件,什麼是OData呢?OData的全名是Open Data Protocol ,它與WCF Data Services其實是同樣的東西,它的最只要目的是希望透過HTTP的方式簡單的來操作資料,透過它開發人員不需要再自行撰寫HTTP Handler或是使用WCF 方式、或是實做Web Service方式來操作資料了。

在去年,其實筆者也有介紹過WebMatrix系列的開發,因為在開發資料庫應用程式時通常會使用OData Helper元件,什麼是OData呢?OData的全名是Open Data Protocol ,它與WCF Data Services其實是同樣的東西,它的最只要目的是希望透過HTTP的方式簡單的來操作資料,透過它開發人員不需要再自行撰寫HTTP Handler或是使用WCF 方式、或是實做Web Service方式來操作資料了。

而為什麼說OData其實就是WCF Data Services 呢,其實您可以將WCF Data Services看做是資料的服務端,它以WCF為基礎的方式實做,將EDM或是其他種類的資料公開至HTTP,而OData您可以把他想做是,就像是在Silverlight的RIA Services 在Browser的Plug-In 操作遠端的EDM的一樣(一種Proxy的機制)。它所傳遞的資料可以是ATOM:application/atom+xml或是JSON格式。對OData 的SPEC有興趣的可以參考http://www.odata.org/developers/protocols/overview

在WebMatrix安裝OData有兩種方式:

  • 從ASP.NET Web Pages 管理頁面來安裝

      image

      image

如下面的開放出資料庫 Northwind 的Orders 資料表的WCF Data Services:

   1:      public static void InitializeService(DataServiceConfiguration config)
   2:      {
   3:          // TODO: 設定規則,指出哪些實體集及服務作業可見、可更新等等。
   4:          // 範例:
   5:          config.SetEntitySetAccessRule("Orders", EntitySetRights.AllRead);
   6:          config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
   7:          config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
   8:      }

 

 

 

您可以在WebMatrix 中撰寫如下程式碼取得如上WCF Data Services 的資料:

   1:  <!DOCTYPE html>
   2:  @{
   3:      var result = OData.Get("http://localhost:56806/WebNorthwindDataServices/WcfSPDataService.svc/Orders/");
   4:      var grid = new WebGrid(result);
   5:  }
   6:  <html lang="en">
   7:      <head>
   8:          <meta charset="utf-8" />
   9:          <title></title>
  10:      </head>
  11:      <body>
  12:          @grid.GetHtml()
  13:      </body>
  14:  </html>

 

 

 

上面的ASP.NET Razor 程式碼取到的資料如下圖所示:

image

 

對於 WebMatrix 快速開發的特性與方便好用的 OData 相信其實許多人也都已經體驗過了,筆者今天想來點不一樣的東西,如果我有個需求,要在WebMatrix的CSHTML的畫面上快速的取得RSS的資料,如同使用OData Helper一般,那麼我們就必須實作一個RSS的元件的Helper (下面之後稱做RSSDataHelper)。我們希望在WebMatrix撰寫一行程式碼即可取得 奇摩新聞-科技 http://tw.news.yahoo.com/rss/techRSS新聞資訊。

下圖為奇摩新聞-科技 的RSS訊息內容:

image

 

開發 RSSDataHelper 資料存取元件有兩種實作方式,一種是透過LINQ to RSS (可在CodeProject 下載)、另一種是使用.NET Framework本身就提供的 LINQ to XML,就省掉這個步驟不在另行下載該LINQ to RSS 的元件,其實只要了解 RSS 的格式同樣可以實作出來。

為了完成 RSSDataHelper 資料存取元件,我們依照以下步驟進行:

(1)、首先建立一個.NET Framework 4.0 的 Class 專案,專案名稱取名為 RSSDataHelper。

(2)、撰寫如下程式碼。

   1:  public class RSSData
   2:      {
   3:          static List<Rss> GetRssData(string RSSXml)
   4:          {
   5:              XDocument XDoc = XDocument.Parse(RSSXml);
   6:   
   7:              var records = from results in XDoc.Descendants("item")
   8:                            select results;
   9:   
  10:              var items = new List<Rss>();
  11:              foreach (var item in records)
  12:              {
  13:                  items.Add(new Rss((string)item.Element("title").Value,
  14:                        (string)item.Element("link").Value,
  15:                        (string)item.Element("pubDate").Value));
  16:              }
  17:              return items;
  18:          }
  19:   
  20:          static string GetRssXml(string Url)
  21:          {
  22:              WebRequest request = HttpWebRequest.Create(Url);
  23:              WebResponse response = request.GetResponse();
  24:              Stream stream = response.GetResponseStream();
  25:              StreamReader reader = new StreamReader(stream);
  26:              try
  27:              {
  28:                  return reader.ReadToEnd();
  29:              }
  30:              finally
  31:              {
  32:                  if (response != null)
  33:                      response.Close();
  34:              }
  35:          }
  36:   
  37:          public static List<Rss> Get(string Url)
  38:          {
  39:              try
  40:              {
  41:                  string RSSXml = GetRssXml(Url);
  42:                  return GetRssData(RSSXml);
  43:              }
  44:              catch (Exception ex)
  45:              {
  46:                  throw ex;
  47:              }
  48:              
  49:          }
  50:      }

 

 

(3)、將編譯好的 RSSDataHelper.DLL 放置在網站的bin目錄下。

image

 

(4)、接著在WebMatrix撰寫如下CSHTML頁面,先試著將Title 秀出來看一下結果。 (記得將RSSDataHelper using 進來)

image

此時點選執行,此 RssPage.cshtml 頁面的執行結果應該是如下:

image

這時的畫面我們已經可以點選RSS的連結,查看新聞內容,但是這還不是我們要的,筆者想做的是像最前面的 WebGrid 一樣,接受一個傳回值後一樣透過一個GetHtml() 方法即得到與 WebGrid 相同的結果,這才是我要的結果 。只不過 WebGrid 的Constructor 所接收的為一般資料來源 IEnumerable<dynamic>,在大概看了一下做法之後,筆者比較傾向自己開發一個 RssGrid 類別,直接接受我的 List<Rss> 物件,因此二話不說,進入到第(5) 步驟。

(5)、撰寫自己的 RssGrid

在 RSSDataHelper 專案中新增一個 RssGrid 類別,並撰寫如下程式碼:

   1:  public class RssGrid
   2:      {
   3:          List<Rss> Items = null;
   4:          public RssGrid(List<Rss> items)
   5:          {
   6:              Items = items;
   7:          }
   8:   
   9:          public HtmlString GetHtml()
  10:          {
  11:              RSSData rssData = new RSSData();
  12:              StringWriter sw = new StringWriter();
  13:              HtmlTextWriter htw = new HtmlTextWriter(sw);
  14:   
  15:              GridView grid = new GridView();
  16:              DataTable dt = new Utility().GetDataTableSchemaByRss(new Rss());
  17:   
  18:              foreach (Rss r in Items)
  19:              {
  20:                  DataRow dr = dt.NewRow();
  21:                  dr["Title"] = r.Title;
  22:                  dr["Link"] = r.Link;
  23:                  dr["PubDate"] = r.PubDate;
  24:                  dt.Rows.Add(dr);
  25:              }
  26:              grid.DataSource = dt;
  27:              grid.AllowSorting = false;
  28:              grid.AllowPaging = false;
  29:              grid.DataBind();
  30:   
  31:              for (int i = 0; i < grid.Rows.Count; i++)
  32:              {
  33:                  TableCell cell = grid.Rows[i].Cells[1];
  34:                  string text = cell.Text;
  35:                  HyperLink link = new HyperLink();
  36:                  link.NavigateUrl = text;
  37:                  link.Target = "_blank";
  38:                  link.Text = "連結";
  39:                  cell.Controls.Add(link);
  40:              }
  41:   
  42:              grid.RenderControl(htw);
  43:   
  44:              byte[] b = System.Text.Encoding.Convert(Encoding.UTF8, Encoding.Default, System.Text.Encoding.UTF8.GetBytes(sw.ToString()));
  45:              string html = Encoding.Default.GetString(b);
  46:   
  47:              return new HtmlString(html);
  48:          }
  49:      }

 

 

(6)、這時 RssPage.cshtml 的程式碼我們可以改成如下:

   1:  @using RSSDataHelper
   2:   
   3:  @{
   4:      var items = RSSData.Get("http://tw.news.yahoo.com/rss/tech");
   5:      RssGrid grid = new RssGrid(items);
   6:  }
   7:  <!DOCTYPE html>
   8:   
   9:  <html lang="en">
  10:      <head>
  11:          <meta charset="utf-8" />
  12:          <title></title>
  13:      </head>
  14:      <body>
  15:          @grid.GetHtml()
  16:      </body>
  17:  </html>

 

 

這時程式的執行結果會是如下,有沒有很像呢?就向操作 OData 使用WebGrid 產出 Grid一般,比較有成就感一點了吧!

image

下一篇筆者再繼續介紹其他的應用。

謝謝各位。


 

簽名:

學習是一趟奇妙的旅程

這當中,有辛苦、有心酸、也有成果。有時也會有瓶頸。要能夠繼續勇往直前就必須保有一顆最熱誠的心。

軟體開發之路(FB 社團)https://www.facebook.com/groups/361804473860062/

Gelis 程式設計訓練營(粉絲團)https://www.facebook.com/gelis.dev.learning/


 

如果文章對您有用,幫我點一下讚,或是點一下『我要推薦,這會讓我更有動力的為各位讀者撰寫下一篇文章。

非常謝謝各位的支持與愛護,小弟在此位各位說聲謝謝!!! ^_^