【www.gdgbn.com--ASP.NET MVC】


淘宝书店:http://shop35357269.taobao.com
alimama_pid="mm_10096109_566393_892186"; alimama_titlecolor="0000FF"; alimama_descolor ="000000"; alimama_bgcolor="FFFFFF"; alimama_bordercolor="E6E6E6"; alimama_linkcolor="008000"; alimama_bottomcolor="FFFFFF"; alimama_anglesize="0"; alimama_bgpic="0"; alimama_icon="0"; alimama_sizecode="11"; alimama_width=760; alimama_height=90; alimama_type=2;
alimama_pid="mm_10096109_566393_1843170"; alimama_titlecolor="0000FF"; alimama_descolor ="000000"; alimama_bgcolor="FFFFFF"; alimama_bordercolor="E6E6E6"; alimama_linkcolor="008000"; alimama_bottomcolor="FFFFFF"; alimama_anglesize="0"; alimama_bgpic="0"; alimama_icon="0"; alimama_sizecode="12"; alimama_width=468; alimama_height=60; alimama_type=2;

google_ad_client = "pub-6430022987645146"; google_ad_slot = "8067578699"; google_ad_width = 250; google_ad_height = 250;
Rss在web系统中相当常见,主要用于快速浏览站点更新的文章等内容,是web2.0的主要特性之一,以前我们是如何来实现Rss输入的呢?在aspx中输出?自定义HttpHandle?自然是可以,但是到了MVC框架中,我们可以选中更好的方式,自定义ActionResult.
根据官方资料,每个Action都要返回一个ActionResult来执行View,而ActionResult是一个抽象类,我们现在必须的就是自定义一个RssAction. 首先根据需要建立一个ArticleResultDemo的Asp.Net Web Application.然后根据mvc约定建立相关文件夹和文件,为了实现rss输出,我添加以下文件,如图:


 
在Models中,ArticleEntity是Article对应实体,ArticleModel有一个测试方法供返回一组ArticleEntity,EntityExtensions是对Entity提供一组扩展方法,进行比如生成rss等功能,RssEntity是提供rss数据实体.在Controllers中,RssResult就是我们扩展的ActionResult,DemoController是扩展的Controller类,提供快捷的Rss输出方法,这是一个抽象类,ArticleController是当前Demo的主控制类.
关于这几个Entity类要说明下,RssEntity文件中包含RssEntity,RssImage,RssItem3个类,对整个rss数据进行了封装.EntityExtersions类提供一组扩展方法来实现实体-rss xml数据的转换,具体EntityExtersions的代码如下:

public static string ToXmlString(this RssItem item)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("");
            sb.Append(ToXmlItem(item));
            sb.AppendLine("
");
            return sb.ToString();
        }

        public static string ToXmlString(this RssImage image)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("");
            sb.Append(ToXmlItem(image));
            sb.AppendLine("");
            return sb.ToString();
        }

        public static string ToXmlString(this RssEntity rss)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("");
            sb.AppendLine("");
            sb.AppendLine("");
            sb.AppendLine(ToXmlItem(rss));
            sb.AppendLine("
");
            sb.AppendLine("");
            return sb.ToString();
        }

        public static RssEntity ToDefaultRss(this IList 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;
        }

        private static string ToXmlItem(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}rn", p.Name.ToLower(), p.GetValue(data, null));
                }
                else if (p.PropertyType == typeof(RssImage))
                {
                    sb.AppendLine(((RssImage)p.GetValue(data, null)).ToXmlString());
                }
                else if (p.PropertyType == typeof(IList))
                {
                    IList rssItems = p.GetValue(data, null) as IList;
                    foreach (RssItem item in rssItems)
                    {
                        sb.AppendLine(item.ToXmlString());
                    }
                }
                else
                {
                    sb.AppendFormat("<{0}>rn", p.Name.ToLower(), p.GetValue(data, null));
                }
            }
            return sb.ToString();
        }
 
通过这些方法,我们可以方便生成rss数据.
再看RssResult类.该类继承自ActionResult类,实现了ExecuteResult方法.该方法为: ExecuteResult(ControllerContext context)我们可以在其中直接将rss数据输出.这便是ActionResult的魅力了,我们通过RssEntity+RssAction完全对实体-xml输出进行了封装,使得程序可以非常方便的实现rss输出.现给出RssResult的代码:
 
由于这两个Rss方法并非Action,因此加上了[NonAction]的Attubite.
现在我们再使用就非常方便了,在ArticleController中,实现一个Rss方法
 
一部直接输出了rss.最后修改web.config,添加route等完成之后,执行图如下:

 
说明一下,在priview3的官方说明中,为了使得默认首页可用,可以添加一个default.aspx文件,然后在页面中加入一行
<% Response.Redirect("article/rss")%>
我看到有朋友质疑说这个语法错误了,没有加分号,其实这是.net默认语言的问题,如果你不修改.net的配置,默认aspx的语言是vb.net的,因此这行是没有任何问题的.
最后给出该Demo的全部工程文件下载.
点击下载该工程文件 
个人Blog同步更新:http://blog.leven.com.cn/Article_28.aspx
public ActionResult Rss()
        {
            RssEntity rss = ArticleModel.GetList().ToDefaultRss();
            return Rss(rss);
        }

public Encoding ContentEncoding { get; set; }

        public RssEntity Data { get; set; }

        public RssResult()
        {
        }

        public RssResult(Encoding encode)
        {
            ContentEncoding = encode;
        }

        public RssResult(RssEntity data, Encoding encode)
        {
            Data = data;
            ContentEncoding = encode;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            HttpResponseBase response = context.HttpContext.Response;
            response.ContentType = "text/xml";
            if (ContentEncoding != null)
            {
                response.ContentEncoding = ContentEncoding;
            }
            if (Data != null)
            {
                response.Write(Data.ToXmlString());
            }
        }

 
为了更方便使用这个RssResult,我们可以对Controller进行进一步的改写,这儿我参照了Json方法的方式实现了DemoController,代码如下:

public abstract class DemoController : Controller
    {
        [NonAction]
        public ActionResult Rss(RssEntity rss, Encoding encode)
        {
            RssResult result = new RssResult(rss, encode);
            return result;
        }

        [NonAction]
        public ActionResult Rss(RssEntity rss)
        {
            RssResult result = new RssResult();
            result.Data = rss;
            return result;
        }
}

alimama_pid="mm_10096109_566393_2123463"; alimama_titlecolor="0000FF"; alimama_descolor ="000000"; alimama_bgcolor="FFFFFF"; alimama_bordercolor="E6E6E6"; alimama_linkcolor="008000"; alimama_bottomcolor="FFFFFF"; alimama_anglesize="0"; alimama_bgpic="0"; alimama_icon="0"; alimama_sizecode="12"; alimama_width=468; alimama_height=60; alimama_type=2;
var alimama_pid="mm_10096109_566393_892989"; var alimama_titlecolor="0000FF"; var alimama_descolor ="000000"; var alimama_bgcolor="FFFFFF"; var alimama_bordercolor="E6E6E6"; var alimama_linkcolor="008000"; var alimama_bottomcolor="FFFFFF"; var alimama_anglesize="0"; var alimama_bgpic="0"; var alimama_icon="0"; var alimama_sizecode="11"; var alimama_width=760; var alimama_height=90; var alimama_type=2;

本文来源:http://www.gdgbn.com/asp/14664/