ASP.NET MVC 1.0 Result 几何?

Action的返回值类型到底有几个?咱们来数数看。

ASP.NET MVC 1.0 目前一共提供了以下十几种Action返回结果类型:

1.       ActionResultbase

2.       ContentResult

3.       EmptyResult

4.       HttpUnauthorizedResult

5.       JavaScriptResult

6.       JsonResult

7.       FileResult (base)

8.       FileContentResult

9.       FilePathResult

10.   FileStreamResult

11.   RedirectResult

12.   RedirectToRouteResult

13.   ViewResultBase(base)

14.   ViewResult

15.   PartialViewResult

 

一个列表下来看得人眼花缭乱,因为可用的Result很多,接着再瞧瞧类关系图以佐辨析:

 

 <图>

 

如图中可见,ActionResult可谓人丁兴旺,目前膝下有儿9子(如图中红色所圈的类),ViewResultBaseFileResult又各有子两三口,这些儿孙们各司所长。那么各个 Result 都会干点啥事儿呢?这个问题说来话长,不过根据诸如“虎父无犬子”、“种瓜得瓜,种豆得豆”、“龙生龙,凤生凤,老鼠的孩子打地洞”的俗语,孩子们多少从他爹那儿遗传了点什么,所以要说明它们的才干之前,得先唠叨唠叨一下 ActionResult这个爹,这个爷,因此这事情还是得先从ActionResult说起。

 

二、朴实的 ActionResult

 

所有的 Result 都派生自 ActionResult抽象类,因此 ActionResult 作为基类提供了最基础的功能,ActionResult 是一个抽象类,其声明如下:

 

public abstract class ActionResult {

 

        public abstract void ExecuteResult(ControllerContext context);

 

}

 

看看普通人民、相貌平平的ActionResultActionResult 是个朴素老百姓,没啥特长,就一个 ExecuteResult() 抽象方法,这个ExecuteResult() 抽象方法还啥都不干,遗传给儿女孙子们让它们去发挥,那么它的责任其实就很明确了,它就是为遗传作准备的,繁殖下一代用的,是只公猪种。因为ActionResult是所有Result的基类,因此你可以在所有的Action上使用它作为返回值类型,而无需动脑筋来明确与返回值相同的类型。

 

二、         EmptyResult

 

EmptyResult ActionResult 最没用的儿子,虽然生儿都想生孙仲谋,希望儿子们都是八斗之才,国家栋梁,可惜第一胎 EmptyResult 就严重破坏了它的梦想,看来也只能痛恨自己种子不够好。咱来瞧瞧这个没用的阿斗:

 

//表示一个啥都不干的结果,就像 controller action 返回 null

    public class EmptyResult : ActionResult {

 

        private static readonly EmptyResult _singleton = new EmptyResult();

 

        internal static EmptyResult Instance {

            get {

                return _singleton;

            }

        }

 

        public override void ExecuteResult(ControllerContext context) {

        }

    }

 

EmptyResult 遗传并实现了ActionResultExecuteResult()方法,同时也遗传了ActionResult的天真朴实的想法,也想“还是等下一代吧”,它有点老子的“无为”味道,所以它的ExecuteResult()方法像足了它的老爹,啥也不干。

 

EmptyResult 类使用了简单的单例模式,看来这样不思进取的儿子,整个家族里头生一个就够糟糕了,用广东人的话说,生它还不如生块叉烧肉。

 

Action中,若要返回一个空的页面(不常用),则可如下:

 

public ActionResult Index()

{

return new EmptyResult();

}

 

执行后页面将缺省返回一个body为空的HMTL架构:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head>
<meta content="text/html; charset=gb2312" http-equiv=content-type></head>
<body></body></html>

 

三、RedirectResult

EmptyResult的“无为”给ActionResult 的打击着实不小,只好将期待落在其他孩子身上,RedirectResult虽然不是什么大才,起码有一技之长,我们看看它的 ExecuteResult() 方法:

 

public override void ExecuteResult(ControllerContext context) {

            if (context == null) {

                throw new ArgumentNullException("context");

            }

 

            string destinationUrl = UrlHelper.Content(Url, context.HttpContext);

            context.HttpContext.Response.Redirect(destinationUrl, false /* endResponse */);

        }

 

RedirectResult用于执行转移。事实上 RedirectResult 最终调用了 Response.Redirect() 进行转移,所以您可以使用RedirectResult跳转到任意的包括当前项目或网络上的Url,例如:http://www.cnblogs.com,对于当前项目的路径,因为使用了UrlHelper.Content() 方法获取目标路径,所以RedirectResult传递的Url同时支持当前项目目录标识符 ~ (即应用程序目录)。

 

四、RedirectToRouteResult

 

RedirectToRouteResult对于RedirectResult而言,其作用有所局限,仅能转移到路由(路由匹配的结果最终是一条相对当前项目的Url,例如: /Home/Index ),总的来说与RedirectResult的最终作用是一样的,都是执行转移。RedirectResult较为直接地转移到任意指定的Url,而RedirectToRouteResult则转移到指定的路由(路由匹配所得结果最终也是一个的Url):

 

public override void ExecuteResult(ControllerContext context) {

            if (context == null) {

                throw new ArgumentNullException("context");

            }

 

            string destinationUrl = UrlHelper.GenerateUrl(RouteName, null /* actionName */, null /* controllerName */, RouteValues, Routes, context.RequestContext, false /* includeImplicitMvcValues */);

            if (String.IsNullOrEmpty(destinationUrl)) {

                throw new InvalidOperationException(MvcResources.ActionRedirectResult_NoRouteMatched);

            }

 

            context.HttpContext.Response.Redirect(destinationUrl, false /* endResponse */);

        }

 

RedirectToRouteResult先通过调用UrlHelper.GenerateUrl()来获得路由匹配所得的最终Url,接着的执行转移过程与RedirectResult相同。

 

路由配置的过程在Global.asax文件中进行,在以MVC模板方式创建的MVC项目中都带有此文件,可在文件中的MvcApplication类的 RegisterRoutes()方法中进行配置路由,该方法缺省的内容如下:

 

public static void RegisterRoutes( RouteCollection routes )

        {

            routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );

 

            routes.MapRoute(

                "Default",                                              // Route name

                "{controller}/{action}/{id}",                           // URL with parameters

                new { controller = "Home", action = "Index", id = ""// Parameter defaults

            );

 

        }

 

RedirectToRouteResult 可跳转至任何一条匹配的路由规则。是以利用路由转移可以跳转到其他控制器的 Action

 

五、ContentResult

 

ContentResult用于将字符串直接向客户端输出。ContentResultExecuteResult方法实际上是调用了 Response.Write( string… ),输入并无特别之处,但是在 ASP 时代,这个Response.Write() 却是可以纵横页面。从输出一个简单的字符串到整个页面,Response.Write()都能胜任,所以ContentResult显得特别强大:

 

public override void ExecuteResult(ControllerContext context) {

            if (context == null) {

                throw new ArgumentNullException("context");

            }

 

            HttpResponseBase response = context.HttpContext.Response;

 

            if (!String.IsNullOrEmpty(ContentType)) {

                response.ContentType = ContentType;

            }

            if (ContentEncoding != null) {

                response.ContentEncoding = ContentEncoding;

            }

            if (Content != null) {

                response.Write(Content);

            }

        }

 

若没有提供任何输出的内容,ContentResult呈现的结果与EmptyResult 是一样的,都是输出最基本的<body>标记内容为空的HTML,若内容不为空,则直接输出这些内容(不再输出其他任何 HTML 代码),例如:

 

public ActionResult Index()

{

return Content( "a" );

}

 

其页面的HTML代码也将只有一个字符 a,要补全所有基本标记需要在字符串中编写,例如:

 

public ActionResult Index()

        {

           return Content( "<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">" +

                              "<html>" +

                                "<head><meta content=""text/html; charset=gb2312"" http-equiv=content-type></head>" +

                               "<body>" +

 

                                "abc" +

 

                                "</body>" +

                              "</html>"

                        );

        }

 

当然不建议使用此方法来输出页面标记,ContentResult 用在Ajax中颇为合适,因为只要内容不为空,输出的字符串与传送到客户端的内容一致,没有额外的附加内容。

 

事实上从ContentResult我们可以看到一个ActionResult其实并无特别,从前面几个Result 来看,其实不过是Response.RedirectResponse.Write,此外还可以利用二进制流Response.OutputStream.Write向客户端上载文件……据此我们所以拓展编写更多针对实际意义的Result。例如 XmlResult(文件)、RssResult(跟XmlResult其实是一样的)等等。

 

六、JsonResult

 

JsonResult首先将指定的对象序列化为Json字符串,然后将字符串写入到HTTP输出流。撇开对象序列化为Json字符串这一过程,实际上与ContentResult其实是一样的,因为JsonResultContentResult都是调用Response.Write()HTTP输出流写入一些内容。所以对此不再赘述:

 

public override void ExecuteResult(ControllerContext context) {

            if (context == null) {

                throw new ArgumentNullException("context");

            }

 

            HttpResponseBase response = context.HttpContext.Response;

 

            if (!String.IsNullOrEmpty(ContentType)) {

                response.ContentType = ContentType;

            }

            else {

                response.ContentType = "application/json";

            }

            if (ContentEncoding != null) {

                response.ContentEncoding = ContentEncoding;

            }

            if (Data != null) {

                // The JavaScriptSerializer type was marked as obsolete prior to .NET Framework 3.5 SP1

#pragma warning disable 0618

                JavaScriptSerializer serializer = new JavaScriptSerializer();

                response.Write(serializer.Serialize(Data));

#pragma warning restore 0618

            }

        }

 

有个地方想唠叨两句,在代码中的:

response.ContentType = "application/json";

 

若要直接向页面输出的话需要更改为文本类型,例如 text/html,否则你要以文件形式下载JsonResult的结果内容。不过这对于将Json用于Ajax而言不会有什么影响。

 

七、JavaScriptResult

 

道与 JsonResultContentResult相同。所以也不赘述,徒费唇舌:

 

public override void ExecuteResult(ControllerContext context) {

            if (context == null) {

                throw new ArgumentNullException("context");

            }

 

            HttpResponseBase response = context.HttpContext.Response;

            response.ContentType = "application/x-javascript";

 

            if (Script != null) {

                response.Write(Script);

            }

        }

 

八、HttpUnauthorizedResult

 

HttpUnauthorizeResult 设置客户端错误代号为 401,即未经授权浏览状态,若设置了Form验证并且客户端没有任何身份票据,那么将转跳到指定的页面(例如登陆页):

 

public override void ExecuteResult(ControllerContext context) {

            if (context == null) {

                throw new ArgumentNullException("context");

            }

 

            // 401 is the HTTP status code for unauthorized access - setting this

            // will cause the active authentication module to execute its default

            // unauthorized handler

            context.HttpContext.Response.StatusCode = 401;

        }

 

可以学习HttpUnauthorizeResult来编写更多同类的返回结果,例如设置 Response.StatusCode = 404,这个是常见的“页面未找到”错误,403 禁止访问等等。

 

九、FileResult

 

FileResult是一个抽象类,主要属性包括声明内容类型信息ContentType 及文件名称FileDownloadName,客户端下载工具中将显示此名称(如果有指定,ContentType可指定任意非空字符串),如果不指定文件名,ContentType需要正确指定,否则无法识别待下载的文件类型。

 

FileResult 用作其他向客户端上载文件的类的基类。

 

十、FilePathResult

 

FilePathResult 继承自 FileResult,使用 FilePathResult 类向客户端上载文件只需要给出文件的路径即可。FilePathResult 将调用 Response.TransmitFile() 传输该文件:

 

protected override void WriteFile(HttpResponseBase response) {

            response.TransmitFile(FileName);

        }

 

十一、FileContentResult

 

FileContentResult继承自 FileResult

 

FileContentResult 将指定的字节内容写入二进制流(客户端将以文件形式下载),对比 FilePathResult 所不同的是 FilePathResult是给出文件路径,然后将整份文件上载给客户,而 FileContentResult 则可以传输某一个字节数组,例如:

 

public ActionResult Index()

{

return File( System.Text.Encoding.UTF8.GetBytes( "你好吗" ), "unknown", "t.txt" );

}

 

FileContentResult 使用 Response.OutputStream.Write 输出内容:

protected override void WriteFile(HttpResponseBase response) {

            response.OutputStream.Write(FileContents, 0, FileContents.Length);

}

 

十二、FileStreamResult

 

FileStreamResult 继承自 FileResult

 

FileStreamResult 向指定文件流读取数据,其他的内容与FileContentResult道同。请参考FileContentResult

转载于:https://www.cnblogs.com/stalwart/archive/2010/06/27/1766091.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

针对SharePointFarm场时安装部署OWA的步骤

下面文章列出针对SharePointFarm场时安装部署OWA的步骤&#xff1a; http://blogs.technet.com/b/meamcs/archive/2013/03/27/office-web-apps-2013-multi-servers-nlb-installation-and-deployment-for-sharepoint-2013-step-by-step-guide.aspx转载于:https://www.cnblogs.co…

mysql双机互备linux成功的_配置MySQL双机热备 - Linux服务器MySQL双机热备份试验_数据库技术_Linux公社-Linux系统门户网站...

二、配置MySQL双机热备传统模式都是采用MySQL双机互备&#xff0c;至于双机热备我搜索了大量的精华帖子都没有发现安装配置文档。故我的一个想法产生了&#xff1a;当建立新的数据库时&#xff0c;默认会建立到/usr/local/mysql/data这里&#xff0c;如果能改掉默认配置文件my.…

万字总结:开源软件通识基础课第三周知识点总结

我们在前两周的课程上&#xff08;第一周、第二周&#xff09;&#xff0c;系统讲授了 FOSS 的课程内容&#xff0c;第三周&#xff0c;我们开始进入 COSS&#xff08;商业开源&#xff09;的部分。本导学班在调研全球开源教育与课程的基础上&#xff0c;通过收集、整理、理解、…

CISCO IOS SLB服务器负载均衡

CISCO IOS SLB在多台服务器之间智能地均衡TCP/IP流量&#xff0c;是一种4层或7层交换功能。目前只有catalyst 6500支持。推荐在在catalyst 6500交换机中选择ACE服务模块&#xff0c;不仅能提供16Gbit/s的性能&#xff0c;而且还能通过SSL加密和双向内容检查实现安全性。优点&a…

掌握深度学习,为什么要用 PyTorch、TensorFlow 框架?

全世界只有3.14 % 的人关注了爆炸吧知识自从2012年深度学习再一次声名鹊起以来&#xff0c;许多机器学习框架都争先恐后地要成为研究人员和行业从业者的新宠。面对如些众多的选择&#xff0c;人们很难判断最流行的框架到底是什么。在某些情况下&#xff0c;深度学习或深度迁移学…

SharePoint 2010 中的BCS身份验证模式

BCS&#xff08;Business Connectivity Services&#xff09;是SharePoint 2010中用于替换原先Microsoft Office SharePoint Server 2007企业版的业务数据目录&#xff08;Business Data Catalog &#xff0c;简称BDC&#xff09;的一项新服务。 BCS相比BDC而言有许多改进&…

SD卡读写扇区注意事项(转)

源&#xff1a;http://blog.163.com/zhaojun_xf/blog/static/30050580201151410635516/ 在调试SD卡时&#xff0c;大家都喜欢使用扇区进行验证。也就是说&#xff0c;一般都是通过读写扇区数据进行比较&#xff0c;或者读取第0扇区的数据&#xff0c;在通过WinHex软件打开启动扇…

mysql用in查询list_Mysql优化器对in list的处理

select * from table where id in (....)这样的查询&#xff0c;是走范围索引还是走等值索引&#xff1f;select * from table where key_part1 in (....) and key_part2XX;这样的查询&#xff0c;第二部分还走不走索引&#xff1f;测试目的&#xff0c;想知道&#xff0c;MYSQ…

开源软件通识基础:第二周课程回顾与总结

接第一篇《开源软件通识基础&#xff1a;第一周课程回顾与总结》&#xff0c;本文为第二周课程内容的回顾与总结。本导学班在调研全球开源教育与课程的基础上&#xff0c;通过收集、整理、理解、拓展国际最新的前沿开源课程&#xff0c;采取众创的模式&#xff0c;由 X-lab 核心…

心情分享

很快&#xff0c;毕业半年多了也工作半年了。回过头想想这段时间更多的是思考&#xff0c;想说的是自己的认识&#xff0c;能做的只有更加的努力。现在都把大学生和民工做比较&#xff0c;甚至有人说大学生还不如民工。是对还是错&#xff1f;谁的错&#xff0c;没有衡量的依据…

mysql数据连接查询_mysql数据库 连接查询

左连接&#xff1a;select 列1&#xff0c;列2&#xff0c;列N fromtableA left join tableBon tableA.列 tableB 【此次表连接成一张大表&#xff0c;完全当成普通表看】where group ,having...照常写例&#xff1a;select goods_id,goods.cat_id,cat_name,goods_name,sho…

在DataGrid中合并单元格行

最近在做项目的时候经常遇到要合并单元格的情况&#xff0c;发现这个东西.net中并没有现成的方法&#xff0c;研究了一下&#xff0c;总结了两种方法。 这个主要都是行合并的&#xff0c;有以下两种情况 1、多行合并为一行&#xff0c;其中将某个或某几个单元格的内容合并起来 …

封装log4cp p

log4cpp 是参考 log4j 所写的 c 版本的写 log 的库。可以在这里下载http://log4cpp.sourceforge.net/我的使用方法是&#xff1a;1&#xff0c;定义了一个 _LOG4CPP 宏&#xff0c;用来打开或关闭 log4cpp 的调用&#xff0c;以便在完全不需要 log 的情况下可以运行&#xff0c…

这些口碑炸裂的BBC神片,就是给孩子最好的生命教育

全世界只有3.14 % 的人关注了爆炸吧知识对孩子来说&#xff0c;好的纪录片就像是打开了一扇新世界的大门&#xff0c;让他们了解了更多大自然的奇妙之处。所以这次我们精心挑选了几部适合儿童观看的纪录片&#xff0c;其中绝大多数是导演专门为孩子拍摄的&#xff0c;大家可以在…

依赖注入生命周期

介绍依赖注入只负责由其创建的对象实例容器或者子容器释放的时候&#xff0c;会释放由其创建的对象实例。推荐使用容器来来管理我们的对象的创建和释放。操作为了演示&#xff0c;我们创建一个UserService&#xff0c;并让该Service继承IDisposablepublic class UserService : …

常用网络面试题一

1、 win2000,win2003个有几个版本&#xff0c;每个版本最新系统补丁包是什么啊&#xff1f; 2、 DNS的实现方法&#xff1f; 3、 WEB服务器的负载均衡&#xff1f; 4、 请问目前市面上常用几种网络操作系统的优缺点&#xff1f; 5、 请问你用过那些服务器&#xff1f;请讲述rai…

《划时代-51单片机C语言全新教程》-第四章 工程创建与深入 概览

&#xff08;请复制整个下载地址到迅雷、快车、QQ旋风进行下载&#xff09; 电子书下载地址&#xff1a;http://files.cnblogs.com/wenziqi/划时代&#xff0d;51单片机C语言全新教程.rar转载于:https://www.cnblogs.com/wenziqi/archive/2010/07/05/1771281.html

java模拟火车站买票的过程_Java常用代理

在我们通常的应用中&#xff0c;代理模式也是我们常用的设计模式之一。所谓的代理模式是指客户端并不直接调用实际的对象&#xff0c;而是通过调用代理对象&#xff0c;来间接的调用实际的对象。为什么要采用这种间接的形式来调用对象呢&#xff1f;一般是因为客户端不想访问实…

网络繁杂,我们该如何准确获取所需信息?

全世界只有3.14 % 的人关注了爆炸吧知识网络已经成为了很多人发表言论的地方不少网站亦难免存在宣泄情绪的内容网络繁杂&#xff0c;该如何获取准确信息&#xff1f;下面为你推荐一些客观公号希望能让你扩展视野&#xff0c;增长见识&#xff01;【关注方式 】1 - 搜索公众号ID…

.NET 6 新特性 WaitAsync

.NET 6 新特性 WaitAsyncIntro在 .NET 6 里新增加了一个 WaitAsync 的方法&#xff0c;用来异步地等待一个任务完成&#xff0c;异步等待的时候可以指定一个 Timeout 时间或者一个取消令牌 CancellationToken&#xff0c;在之前的版本中只有一个同步的 Wait 会等待任务的完成&a…