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("<item>");
            sb.Append(ToXmlItem<RssItem>(item));
            sb.AppendLine("</item>");
            return sb.ToString();
        }

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

        public static string 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();
        }

        public static 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 = "yun_qi_img/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>(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}>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<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}>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;
时间: 2024-10-02 09:12:12

Asp.Net MVC实践的相关文章

艾伟_转载:【译】12个asp.net MVC最佳实践

       上一周我我在罗马进行了两场对于开发完成不久的http://www.dotnetromacesta.org/的Asp.net MVC的演讲.而其中一场演讲内容是关于我对于Asp.net MVC最佳实践的看法.因为这场演讲是在意大利进行的,为了大家能更好的阅读,我将演讲所用的ppt翻译成英文. 关于Controller的最佳实践 1-删除AccountController     让Demo代码在你的程序中是一个非常不好的做法.请永远不要使用AccountController. 2-隔

asp.net mvc Partial OutputCache在SpaceBuilder中的应用实践

最近给SpaceBuilder增加OutputCache 时发现了一些问题,贴在这做个备忘,也方便遇到类似问题的朋友查阅. 目前SpaceBuilder 表现层使用是asp.net mvc v1.0,使用了很多RenderAction(关于asp.net mvc的Partial Requests参见Partial Requests in ASP.NET MVC) .希望对于实时性要求不高的内容区域采用客户端缓存来提升性能同时也弥补一下RenderAction对性能的损失. 使用asp.net m

ASP.NET MVC雕虫小技 1-2

看到AnyTao和TerryLee分享的关于ASP.NET MVC使用和优化的技巧,不免手痒,也分享一下这一年多来ASP.NET MVC开发的积累. 其中未必是一些高效的技巧,但是的确是能解决问题,也未必有什么高深的原理,只是我觉得值得分享. 1.Controller来控制HTML的Title 我想大部分朋友都有在Controller里面指定Html页面Title的需求. 我习惯于先写使用的代码再去完善其实现,而指定一个Title最方便的形式莫过于: 1: public ActionResult

为ASP.NET MVC扩展异步Action功能

异步请求处理是ASP.NET 2.0中引入的高级特性,它依托IO Complete Port,对于提高IO密集型应用程 序的吞吐量非常重要(详见原理描述和性能测试).但是目前ASP.NET MVC框架缺少异步Action功能,这 也就是老赵经常挂在嘴边的那个"目前ASP.NET MVC所缺少的非常重要的功能".在TechED 2008 China的 Session中我曾经给出过一个所谓的"解决方案",但是它复杂性之高使那个解决方案有太多限制.为了 弥补TechED上

对ASP.NET MVC项目中的视图做单元测试

关于视图的单元测试 说到ASP.NET MVC,我们似乎始终都在关注对于Controller的测试--虽然Stephen Walther也写过如 何脱离Web Server对View进行单元测试,但是他的方法可看而不可用.复杂的构造和预备,以及对生成的 HTML字符串作判断--这真是在对视图做单元测试吗?仔细分析他的代码可以发现,这其实是在对 ViewEngine做单元测试.而且,如果真要对ViewEngine做单元测试,也不应该像他那样依赖外部文件.在 我看来,他的做法什么都不是--似乎美观,

基于ASP.NET MVC框架开发Web论坛应用程序

我想通过本系列文章从头到尾构建一个完整的ASP.NET MVC论坛应用程序,最终的目的是探讨和推动使用ASP.NET MVC框架构建应用程序的最佳实践. 1.简介 在本篇中,我想先从全局方面介绍一下论坛应用程序的总体目标.在本篇中,我将讨论一下避免代码坏味道的重要性,还将讨论如何利用软件设计原则和模式来帮助你编写适合未来改变的富有弹性的代码.最后,我还将论证一下为什么我选择使用测试驱动开发方式构建本系列文章中的论坛应用程序. 2.什么样的软件是好的软件 我不想仅仅为了构建论坛应用程序而任意构建此

ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作

前言 ASP.NET MVC作为微软官方的MVC解决方案,推出有一段时间了.可以说自动推出以来,一直广受关注.在经历了漫长的Preview 之后,前几天终于推出了其beta版.并且在官方文档中,微软声明最终的正式版与beta版相比不会有大的变化.所以,对于.NET平台的开发人 员来说,是时候学习ASP.NET MVC了. 本系列文章作为一个ASP.NET MVC的入门教程,将不会长篇大论介绍其中的概念及理论.而是通过 案例实践来学习ASP.NET MVC.在这系列文章中我将逐步完成一个"公告发布

ASP.NET MVC Framework与WCSF中MVP模式的比较

概述 MVC模式已经出现了几十年了,在GUI领域已经得到了广泛的应用,由于微软ASP.NET MVC Framework的出现,致使MVC一度成为.NET 社区的热名话题.作为MVC的变种MVP模式,也已经出现好几年了,在微软模式与实践小组提供的Web Client Software Factory中,给出了实现 MVP模式的应用程序最佳实践,本文将试着对这两种实现比较一二. MVC(Model-View-Controller,模型-视图-控制器)模式是80年代 Smalltalk-80出现的一

ASP.NET MVC Contact Manager开发之旅迭代5

迭代5 建立单元测试 本次迭代 在上一次对Contact Manager的迭代中,我们通过使用一些设计模式对 程序进行了重构,松散了类之间的耦合.我们将controller.service和repository层分别 独立出来.每层都基于接口与其他层进行交互. 通过重构,应用程序变得更以维护 和修改.假如某天你需要使用其他的数据存储技术,那么只要简单的替换repository层即可 ,并不需要去碰controller或service层中的代码. 但当我们需要向Contact Manager中添加