自定義ActionResult實現Rss輸出 (基於ASP.NET MVC Preview 3)
阿新 • • 發佈:2018-12-27
前兩天才做了一個Asp.Net MVC Preview2的實踐,沒想到這就升級到了Asp.Net Preview3了,Preview3確實比2好上不少,特別有兩個地方值得注意,一是Route新增了MapRoute方法,可以更方便新增Url路由規則,二是修改了View的部分,使得Action統一返回ActionResult,更方便我們定製View.
中輸出?自定義HttpHandle?自然是可以,但是到了MVC框架中,我們可以選中更好的方式,自定義ActionResult.
有一個測試方法供返回一組ArticleEntity,EntityExtensions是對Entity提供一組擴充套件方法,進行比如生成rss等功能,RssEntity是提供rss資料實體.在Controllers中,RssResult就是我們擴充套件的ActionResult,DemoController是擴充套件的Controller類,提供快捷的Rss輸出方法,這是一個抽象類,ArticleController是當前Demo的主控制類.
類提供一組擴充套件方法來實現實體-rss xml資料的轉換,具體EntityExtersions的程式碼如下:
publicstaticstring ToXmlString(this RssItem item)
{
StringBuilder sb =new StringBuilder();
sb.AppendLine("<item>");
sb.Append(ToXmlItem<RssItem>(item));
sb.AppendLine("</item>");
return sb.ToString();
}
publicstaticstring ToXmlString(this RssImage image)
{
StringBuilder sb =new StringBuilder();
sb.AppendLine("<image>");
sb.Append(ToXmlItem<RssImage>(image));
sb.AppendLine("</image>");
return sb.ToString();
}
publicstaticstring ToXmlString(this RssEntity rss)
{
StringBuilder sb =new StringBuilder();
sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
sb.AppendLine("<rss version=\"2.0\">");
sb.AppendLine("<channel>");
sb.AppendLine(ToXmlItem<RssEntity>(rss));
sb.AppendLine("</channel>");
sb.AppendLine("</rss>");
return sb.ToString();
}
publicstatic RssEntity ToDefaultRss(this IList<ArticleEntity> articleList)
{
RssEntity rss =new RssEntity()
{
Title ="ArticleResult Demo Rss.",
Copyright ="Copyright 2008 Leven",
Generator ="ArticleResult Demo",
Link ="http://blog.leven.com.cn/",
Description ="ArticleResult Demo Rss - a demo of asp.net mvc priview3.",
WebMaster ="leven",
Image =new RssImage()
{
Link ="http://blog.leven.com.cn/images/logo.jpg",
Title ="ArticleResult Demo",
Url ="http://blog.leven.com.cn/",
Description ="ArticleResult Demo Image."
}
};
foreach (ArticleEntity article in articleList)
{
rss.Items.Add(new RssItem()
{
Title = article.Title,
Author = article.PostUser,
Category ="Default Category",
Link ="http://blog.leven.com.cn/",
Guid ="http://blog.leven.com.cn/",
PubData = article.PostTime,
Description = article.Content
});
}
return rss;
}
privatestaticstring ToXmlItem<DType>(DType data)
where DType : class
{
StringBuilder sb =new StringBuilder();
Type type = data.GetType();
PropertyInfo[] pis = type.GetProperties();
foreach (PropertyInfo p in pis)
{
if (p.PropertyType ==typeof(DateTime))
{
sb.AppendFormat("<{0}>{1:R}</{0}>\r\n", p.Name.ToLower(), p.GetValue(data, null));
}
elseif (p.PropertyType ==typeof(RssImage))
{
sb.AppendLine(((RssImage)p.GetValue(data, null)).ToXmlString());
}
elseif (p.PropertyType ==typeof(IList<RssItem>))
{
IList<RssItem> rssItems = p.GetValue(data, null) as IList<RssItem>;
foreach (RssItem item in rssItems)
{
sb.AppendLine(item.ToXmlString());
}
}
else
{
sb.AppendFormat("<{0}><![CDATA[{1}]]></{0}>\r\n", p.Name.ToLower(), p.GetValue(data, null));
}
}
return sb.ToString();
}
public RssEntity Data { get; set; }
今天我要實踐的就是使用Priview3提供的新特性,通過自定義ActionResult實現Rss輸出.
Rss在web系統中相當常見,主要用於快速瀏覽站點更新的文章等內容,是web2.0的主要特性之一,以前我們是如何來實現Rss輸入的呢?在aspx
根據官方資料,每個Action都要返回一個ActionResult來執行View,而ActionResult是一個抽象類,我們現在必須的就是自定義一個RssAction.
首先根據需要建立一個ArticleResultDemo的Asp.Net Web Application.然後根據mvc約定建立相關資料夾和檔案,為了實現rss輸出,我新增以下檔案,如圖:在Models中,ArticleEntity是Article對應實體,ArticleModel
關於這幾個Entity類要說明下,RssEntity檔案中包含RssEntity,RssImage,RssItem3個類,對整個rss資料進行了封裝.EntityExtersions
publicstaticstring ToXmlString(this RssItem item)
{
StringBuilder sb =new StringBuilder();
sb.AppendLine("<item>");
sb.Append(ToXmlItem<RssItem>(item));
sb.AppendLine("</item>");
return sb.ToString();
}
publicstaticstring ToXmlString(this RssImage image)
{
StringBuilder sb =new StringBuilder();
sb.AppendLine("<image>");
sb.Append(ToXmlItem<RssImage>(image));
sb.AppendLine("</image>");
return sb.ToString();
}
publicstaticstring ToXmlString(this RssEntity rss)
{
StringBuilder sb =new StringBuilder();
sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
sb.AppendLine("<rss version=\"2.0\">");
sb.AppendLine("<channel>");
sb.AppendLine(ToXmlItem<RssEntity>(rss));
sb.AppendLine("</channel>");
sb.AppendLine("</rss>");
return sb.ToString();
}
publicstatic RssEntity ToDefaultRss(this IList<ArticleEntity> articleList)
{
RssEntity rss =new RssEntity()
{
Title ="ArticleResult Demo Rss.",
Copyright ="Copyright 2008 Leven",
Generator ="ArticleResult Demo",
Link ="http://blog.leven.com.cn/",
Description ="ArticleResult Demo Rss - a demo of asp.net mvc priview3.",
WebMaster ="leven",
Image =new RssImage()
{
Link ="http://blog.leven.com.cn/images/logo.jpg",
Title ="ArticleResult Demo",
Url ="http://blog.leven.com.cn/",
Description ="ArticleResult Demo Image."
}
};
foreach (ArticleEntity article in articleList)
{
rss.Items.Add(new RssItem()
{
Title = article.Title,
Author = article.PostUser,
Category ="Default Category",
Link ="http://blog.leven.com.cn/",
Guid ="http://blog.leven.com.cn/",
PubData = article.PostTime,
Description = article.Content
});
}
return rss;
}
privatestaticstring ToXmlItem<DType>(DType data)
where DType : class
{
StringBuilder sb =new StringBuilder();
Type type = data.GetType();
PropertyInfo[] pis = type.GetProperties();
foreach (PropertyInfo p in pis)
{
if (p.PropertyType ==typeof(DateTime))
{
sb.AppendFormat("<{0}>{1:R}</{0}>\r\n", p.Name.ToLower(), p.GetValue(data, null));
}
elseif (p.PropertyType ==typeof(RssImage))
{
sb.AppendLine(((RssImage)p.GetValue(data, null)).ToXmlString());
}
elseif (p.PropertyType ==typeof(IList<RssItem>))
{
IList<RssItem> rssItems = p.GetValue(data, null) as IList<RssItem>;
foreach (RssItem item in rssItems)
{
sb.AppendLine(item.ToXmlString());
}
}
else
{
sb.AppendFormat("<{0}><![CDATA[{1}]]></{0}>\r\n", p.Name.ToLower(), p.GetValue(data, null));
}
}
return sb.ToString();
}
通過這些方法,我們可以方便生成rss資料.
再看RssResult類.該類繼承自ActionResult類,實現了ExecuteResult方法.該方法為: ExecuteResult(ControllerContext context)我們可以在其中直接將rss資料輸出.這便是ActionResult的魅力了,我們通過RssEntity+RssAction完全對實體-xml輸出進行了封裝,使得程式可以非常方便的實現rss輸出.現給出RssResult的程式碼:
public RssEntity Data { get; set; }