ActionResult

public abstract class ActionResult

{

public abstract void ExecuteResult(ControllerContext context);

}

  1. EmptyResult

无论一个Action返回值是Void还是其他数据类型,都会创建相应的ActionResult.

如果一个Action方法的返回值时Void或者Null,会生成一个EmptyResult对象.

EmptyResult主要起到了适配器的作用,让所有的用法保持一致.

ActionInvoker中,执行Action方法后,根据返回值判断

protected virtual ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue)
    {

        if (actionReturnValue == null)//Action的返回值为Void或者Null

{

            return new EmptyResult();

        }

        ActionResult actionResult = (actionReturnValue as ActionResult) ??

        new ContentResult { Content = Convert.ToString(actionReturnValue, CultureInfo.InvariantCulture) };//如果返回值不是ActionResult,就创建ContentResult

        return actionResult;

    }

EmptyResult

  1. public class EmptyResult : ActionResult
        {
    
            private static readonly EmptyResult _singleton = new EmptyResult();
    
            internal static EmptyResult Instance
            {
    
                get { return _singleton; }
    
            }
    
            public override void ExecuteResult(ControllerContext context)
            {
    
            }
    
        }

    ContentResult

如果Action的返回值不是ActionResult,就创建ContentResult

ContentResult

public class ContentResult : ActionResult
    {

        public string Content { get; set; }

        public Encoding ContentEncoding { get; set; }

        public string ContentType { get; set; }

        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);

            }

        }

    }

Controller中定义了几个创建ContentResult的封装方法

  1. protected internal ContentResult Content(string content)
        {
    
            return Content(content, null /* contentType */);
    
        }
    
        protected internal ContentResult Content(string content, string contentType)
        {
    
            return Content(content, contentType, null /* contentEncoding */);
    
        }
    
        protected internal virtual ContentResult Content(string content, string contentType, Encoding contentEncoding)
        {
    
            return new ContentResult {
    
                Content = content,
    
                ContentType = contentType,
    
                ContentEncoding = contentEncoding
    
            };
    
        }

    FileResult

可以将某个物理文件的内容给客户端.如果指定了文件名,就采用附件的方式下载文件.

FileResult

public abstract class FileResult : ActionResult
{

    private string _fileDownloadName;

    protected FileResult(string contentType)
    {

        if (String.IsNullOrEmpty(contentType)) {

            throw new ArgumentException(MvcResources.Common_NullOrEmpty, "contentType");

        }

        ContentType = contentType;

    }

    public string ContentType { get; private set; }

    public string FileDownloadName
    {

        get { return _fileDownloadName ?? String.Empty; }

        set { _fileDownloadName = value; }

    }

    public override void ExecuteResult(ControllerContext context)
    {

        if (context == null) {

            throw new ArgumentNullException("context");

        }

        HttpResponseBase response = context.HttpContext.Response;

        response.ContentType = ContentType;

        if (!String.IsNullOrEmpty(FileDownloadName)) {

            string headerValue = ContentDispositionUtil.GetHeaderValue(FileDownloadName);

            context.HttpContext.Response.AddHeader("Content-Disposition", headerValue);

        }

        WriteFile(response);

    }
}

文件下载方式有两种

针对文件的响应具有两种形式,即内联(Inline) 和附件(Attachment) 。一般来说,前者会利用浏览器直接打开响应的文件,而后者会以独立的文件下载到客户端。对于后者,我们一般会为下载的文件指定一个文件名,这个文件名可以通过FileResult 的FileDownloadName 属性来指定。文件响应在默认情况下采用内联的方式,如果需要采用附件的形式,需要为响应创建一个名称为"Content-Disposition" 的报头,该报头值的格式为

"attachment; filename={FileDownloadName} "。

有三种FileResult

  • FileContentResult

针对文件内容创建的FileResult.直接将文件内容写入到Response的OutputStream中

FileContentResult

public class FileContentResult : FileResult
{

    public FileContentResult(byte[] fileContents, string contentType)

        : base(contentType)
    {

        if (fileContents == null) {

            throw new ArgumentNullException("fileContents");

        }

        FileContents = fileContents;

    }

    public byte[] FileContents { get; private set; }

    protected override void WriteFile(HttpResponseBase response)
    {

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

    }

}
  • FilePathResult

根据物理文件路径创建FileResult.调用 response.TransmitFile(FileName)输出文件

FilePathResult

public class FilePathResult : FileResult
{

    public FilePathResult(string fileName, string contentType)

        : base(contentType)
    {

        if (String.IsNullOrEmpty(fileName)) {

            throw new ArgumentException(MvcResources.Common_NullOrEmpty, "fileName");

        }

        FileName = fileName;

    }

    public string FileName { get; private set; }

    protected override void WriteFile(HttpResponseBase response)
    {

        response.TransmitFile(FileName);

    }

}

  • FileStreamResult

FileStreamResult

public class FileStreamResult : FileResult
{

    private const int BufferSize = 0x1000;

    public FileStreamResult(Stream fileStream, string contentType)

        : base(contentType)
    {

        if (fileStream == null) {

            throw new ArgumentNullException("fileStream");

        }

        FileStream = fileStream;

    }

    public Stream FileStream { get; private set; }

    protected override void WriteFile(HttpResponseBase response)
    {

        Stream outputStream = response.OutputStream;

        using (FileStream) {

            byte[] buffer = new byte[BufferSize];

            while (true) {

                int bytesRead = FileStream.Read(buffer, 0, BufferSize);

                if (bytesRead == 0) {

                    // no more data

                    break;

                }

                outputStream.Write(buffer, 0, bytesRead);

            }

        }

    }

}

  • Controller中定义的封装方法

  1. JavaScriptResult

貌似和浏览器有关系,谷歌不执行,直接返回字符串了

在服务端生成一段JS,作为响应返回给客户端,并且在客户端执行.

JavaScriptResult就是将ContentType设置为javascript,然后直接写入JS内容,因此,完全可以用ContentResult实现这个效果,只需要设置ContentType的类型为Scrippt就可以了

JavaScriptResult

public class JavaScriptResult : ActionResult
{

    public string Script { get; set; }

    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);

        }

    }

}

  1. JsonResult

默认情况下,不允许Get请求Json数据

JsonResult

public class JsonResult : ActionResult
{

    public JsonResult()
    {

        JsonRequestBehavior = JsonRequestBehavior.DenyGet;

    }

    public Encoding ContentEncoding { get; set; }

    public string ContentType { get; set; }

    public object Data { get; set; }

    public JsonRequestBehavior JsonRequestBehavior { get; set; }

    public int? MaxJsonLength { get; set; }

    public int? RecursionLimit { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {

        if (context == null) {

            throw new ArgumentNullException("context");

        }

        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&

        String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) {

            throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed);

        }

        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) {

            JavaScriptSerializer serializer = new JavaScriptSerializer();

            if (MaxJsonLength.HasValue) {

                serializer.MaxJsonLength = MaxJsonLength.Value;

            }

            if (RecursionLimit.HasValue) {

                serializer.RecursionLimit = RecursionLimit.Value;

            }

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

        }

    }

}

JsonRequestBehavior

public enum JsonRequestBehavior

{

AllowGet,

DenyGet,

}

  1. HttpStatusCodeResult

设置Response的StatusCode

HttpStatusCodeResult

public HttpStatusCodeResult(int statusCode, string statusDescription)

{

StatusCode = statusCode;

StatusDescription = statusDescription;

}

public int StatusCode { get; private set; }

public string StatusDescription { get; private set; }

public override void ExecuteResult(ControllerContext context)

{

if (context == null)

{

throw new ArgumentNullException("context");

}

context.HttpContext.Response.StatusCode = StatusCode;

if (StatusDescription != null)

{

context.HttpContext.Response.StatusDescription = StatusDescription;

}

}

  1. RedirectResult/RedirectToRouteResult

客户端的浏览器地址会变化

其作用与调用HttpResponse 的Redirect/RedirectPermanent 方法完全一致

暂时重定向和永久重定向有时又被称为"302 重定向"和"301 重定向", 302 和301 表示响应的状态码。当我们调用HttpResponse 的RedirectIRedirectPermanent 方法时,除了会设置相应的响应状态码之外,还会将重定向的目标地址写入响应报头(Location) ,浏览器在接收到响应之后自动发起针对重定向目标地址的访问。

RedirectResult

public bool Permanent { get; private set; }

public string Url { get; private set; }

public override void ExecuteResult(ControllerContext context)

{

if (context == null)

{

throw new ArgumentNullException("context");

}

if (context.IsChildAction)

{

throw new InvalidOperationException(MvcResources.RedirectAction_CannotRedirectInChildAction);

}

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

context.Controller.TempData.Keep();

if (Permanent)

{

context.HttpContext.Response.RedirectPermanent(destinationUrl, endResponse: false);

}

else

{

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

}

}

RedirectToRouteResult

根据路由生成URL,

再进行重定向

public class RedirectToRouteResult : ActionResult
{

    private RouteCollection _routes;

    public RedirectToRouteResult(RouteValueDictionary routeValues)

        :

        this(null, routeValues)
    {

    }

    public RedirectToRouteResult(string routeName, RouteValueDictionary routeValues)

        : this(routeName, routeValues, permanent: false)
    {

    }

    public RedirectToRouteResult(string routeName, RouteValueDictionary routeValues, bool permanent)
    {

        Permanent = permanent;

        RouteName = routeName ?? String.Empty;

        RouteValues = routeValues ?? new RouteValueDictionary();

    }

    public bool Permanent { get; private set; }

    public string RouteName { get; private set; }

    public RouteValueDictionary RouteValues { get; private set; }

    internal RouteCollection Routes
    {

        get
        {

            if (_routes == null) {

                _routes = RouteTable.Routes;

            }

            return _routes;

        }

        set { _routes = value; }

    }

    public override void ExecuteResult(ControllerContext context)
    {

        if (context == null) {

            throw new ArgumentNullException("context");

        }

        if (context.IsChildAction) {

            throw new InvalidOperationException(MvcResources.RedirectAction_CannotRedirectInChildAction);

        }

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

        if (String.IsNullOrEmpty(destinationUrl)) {

            throw new InvalidOperationException(MvcResources.Common_NoRouteMatched);

        }

        context.Controller.TempData.Keep();

        if (Permanent) {

            context.HttpContext.Response.RedirectPermanent(destinationUrl, endResponse: false);

        } else {

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

        }

    }

}

ViewResult和ViewEngine

  1. View引擎中的View

IView

public interface IView

{

void Render(ViewContext viewContext, TextWriter writer);

}

ViewContext

  1. ViewEngine

IViewEngine

public interface IViewEngine

{

ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);

ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);

void ReleaseView(ControllerContext controllerContext, IView view);

}

ViewEngineResult

public class ViewEngineResult
{

    public ViewEngineResult(IEnumerable<string> searchedLocations)
    {

        if (searchedLocations == null) {

            throw new ArgumentNullException("searchedLocations");

        }

        SearchedLocations = searchedLocations;

    }

    public ViewEngineResult(IView view, IViewEngine viewEngine)
    {

        if (view == null) {

            throw new ArgumentNullException("view");

        }

        if (viewEngine == null) {

            throw new ArgumentNullException("viewEngine");

        }

        View = view;

        ViewEngine = viewEngine;

    }

    public IEnumerable<string> SearchedLocations { get; private set; }

    public IView View { get; private set; }

    public IViewEngine ViewEngine { get; private set; }

}

ViewEngines

public static class ViewEngines
{

    private static readonly ViewEngineCollection _engines = new ViewEngineCollection

{

new WebFormViewEngine(),

new RazorViewEngine(),

};

    public static ViewEngineCollection Engines
    {

        get { return _engines; }

    }

}

ViewEngineCollection

ViewEngineCollection 同样定义了FindViewlF indPartialView 方法用于获取指定名称的View 和分部View

public class ViewEngineCollection : Collection<IViewEngine>
{

    private IResolver<IEnumerable<IViewEngine>> _serviceResolver;

    public ViewEngineCollection()
    {

        _serviceResolver = new MultiServiceResolver<IViewEngine>(() => Items);

    }

    public ViewEngineCollection(IList<IViewEngine> list)

        : base(list)
    {

        _serviceResolver = new MultiServiceResolver<IViewEngine>(() => Items);

    }

    public virtual ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName)
    {

        if (controllerContext == null) {

            throw new ArgumentNullException("controllerContext");

        }

        if (String.IsNullOrEmpty(partialViewName)) {

            throw new ArgumentException(MvcResources.Common_NullOrEmpty, "partialViewName");

        }

        return Find(e => e.FindPartialView(controllerContext, partialViewName, true),

        e => e.FindPartialView(controllerContext, partialViewName, false));

    }

    public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName)
    {

        if (controllerContext == null) {

            throw new ArgumentNullException("controllerContext");

        }

        if (String.IsNullOrEmpty(viewName)) {

            throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewName");

        }

        return Find(e => e.FindView(controllerContext, viewName, masterName, true),

        e => e.FindView(controllerContext, viewName, masterName, false));

    }

}
  1. ViewResult的执行

如果Action的返回值不是ActionResult,就创建ContentResult

时间: 2024-11-09 00:19:18

ActionResult的相关文章

MVC中几种常用ActionResult

一.定义 MVC中ActionResult是Action的返回结果.ActionResult 有多个派生类,每个子类功能均不同,并不是所有的子类都需要返回视图View,有些直接返回流,有些返回字符串等.ActionResult是一个抽象类,它定义了唯一的ExecuteResult方法,参数为一个ControllerContext,下面为您介绍MVC中的ActionResult 的用法 二.什么是ActionResult ActionResult是控制器方法执行后返回的结果类型,控制器方法可以返回

asp.net mvc5 step by step(四)——关于Controller的ActionResult

ActionResult是控制器方法执行后返回的结果类型,控制器方法可以返回一个直接或间接从ActionResult抽象类继承的类型,如果返回的 是非ActionResult类型,控制器将会将结果转换为一个ContentResult类型.默认的ControllerActionInvoker 调用ActionResult.ExecuteResult方法生成应答结果. 一.ActionResult的派生关系图: 二.常见的几种ActionResult 1.ContentResult 返回简单的纯文本

ActionResult的其它返回值

我们上边所看到的Action都是return View();我们可以看作这个返回值用于解析一个aspx文件.而它的返回类型是ActionResult如 public ActionResult Index() { return View(); } 除了View()之外那我们这里还能用于返回什么值呢? 一.ascx页面 场景:要返回代码片断,比如Ajax返回一个子页 我们先新建一个Action public ActionResult Ascx() { return PartialView(); }

ASP.NET MVC 中 ActionResult

ActionResult 是一个抽象(abstract)类,ViewResult 只是ActionResult 的一个实现(implementation).如果你确认你返回的是一个视图(view),你可以直接返回类型为ViewResult.ActionResult 有很多的派生类,如果你很确定你要返回的类型,你可以明确的返回该类型.如果你并不是很清楚,或者你根本不想去理解这些东西,你可以直接返回这些派生类的基类:ActionResult .

控制器-各种ActionResult【2】

控制器-各种ActionResult 我们所看到的Action都是return View();我们可以看作这个返回值用于解析一个aspx文件.而它的返回类型是ActionResult如 public ActionResult Index() { return View(); } 除了View()之外那我们这里还能用于返回什么值呢? <1>ascx页面 场景:要返回代码片断,比如Ajax返回一个子页 让我们先建立一个TestController.cs控制器:我们先新建一个Action publi

控制器-各种ActionResult

<1> MVC笔记 Controller相关技术 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Ajax; using System.IO; namespace DemoRC.Controllers { public class DemoController : Controller {

(七)Action 的返回值 ActionResult

1. 当返回一个页面,return View();  View() 方法的返回值是 ViewResult 类型,继承自 ActionResult. 2. 当重定向一个页面, return Redirect("Path"); Redirect() 方法的返回值类型是 RedirectResult. 3. 直接返回文本内容:ruturn Content("value"); Content() 方法的返回值类型是 ContentResult. 4. 当返回一个文件的时候,

一个ActionResult中定位到两个视图&mdash;&lt;团委项目&gt;

     在使用MVC做项目的时候一般的情况就是一个ActionResult一个视图,这样对应的Return View();就可以找到下面对应的视图,这是根据一个原则,"约定大于配置",但是我们有的时候需要在一个ActionResult中根据业务跳转到不同的视图,展示到界面上. 这里也不一定绝对要跳转到对于的视图,我们可以通过Return RedirectToAction()来跳转到对于的视图,如下 public ActionResult Detail(Guid id) { try {

mvc4里面的ActionResult

通常我们在一个ASP.NET MVC项目中创建一个Controller的时候,Index()方法默认的返回类型都是ActionResult,通过查看UML图,ActionResult实际上是一个抽象类,因此实际返回的类型是该抽象类的子类. Ø ActionResult及其子类的UML图   有关ActionResult及其子类的UML图如下所示: 由于图片比较大,所以在浏览器中看起来可能比较小,也不太方便,大家可以点击这里下载大图,使用专业的图片浏览器打开来看. 下载大图 Ø ActionRes