MVC - Action和ActionResult

时间:2022-11-19 11:52:28

Action

 定义在Controller中的Action方法返回ActionResult对象,ActionResult是对Action执行结果的封装,用于最终对请求进行响应。HTTP是一个单纯的采用请求/回复消息交换模式的网络协议,Web服务器在接收并处理来自客户端的请求后会根据处理结果对请求予以响应,最终的处理体现在针对目标Action方法的执行。

 public class MyController : Controller {
public ActionResult MyActionMethod() {
...
return xxx;
}
}

对Action方法的要求:

  • public的实例方法,返回ActionResult类型;
  • 不能是范型方法,不能被重载;
  • 没有标志NonActionAttribute特性(NoAction);

对controller类的要求:

  • MVC中所有的controller类必须以"Controller"后缀来命名;
 public abstract class ControllerBase : IController
{
public ControllerContext ControllerContext { get; set; }
}
public abstract class Controller : ControllerBase, ...
{
public HttpResponseBase Response { get; }
public HttpContextBase HttpContext { get; }
}
  • 直接利用只读的Response属性表示当前的HttpResponse对象,实现对请求的响应;
  • 间接利用表示当前HTTP上下文的HttpContext属性和表示Controller上下文的ControllerContext属性获取用于响应请求的HttpResponse对象;

 实际中,并不利用HttpResponse直接对请求响应,而是将请求响应实现在一个ActionResult对象中,最终的请求响应实现在抽象方法ExecuteResult()中。

HttpResponseBase response = context.HttpContext.Response

ActionResult

 抽象类,ActionResult是Controller中Action的返回类型,Action方法可以返回一个直/间接从ActionResult抽象类继承的类型。默认ControllerActionInvoker调用ActionResult.ExecuteResult()方法生成请求响应结果。

namespace System.Web.Mvc {
public abstract class ActionResult {
protected ActionResult(); // 构造函数
public abstract void ExecuteResult(ControllerContext context); // 用于子类重写
}
}

EmptyResult

 空结果。如果Action方法返回NULL或void,MVC将其转换成EmptyResult对象。

public class EmptyResult : ActionResult {
public EmptyResult();
public override void ExecuteResult(ControllerContext context);
}

ContentResult

 用户定义的纯文本内容类型,调用Response.Write()将字符串直接向客户端输出。如果Action方法返回非ActionResult对象,MVC将简单地以返回对象的ToString()内容为基础产生一个ContentResult对象并返回。

public class ContentResult : ActionResult {
public ContentResult();
public Encoding ContentEncoding { get; set; }
public string ContentType { get; set; }
public string Content { get; set; }
public override void ExecuteResult(ControllerContext context);
}

其中,contentType是文档类型,contentEncoding是编码方式。

 抽象类Controller定义多个重载方法根据指定的内容、编码方式和媒体类型创建相应的ContentResult对象:

public abstract class Controller : ControllerBase, ... {
protected ContentResult Content(string content, xxx);
protected virtual ContentResult Content(string content, string contentType, Encoding contentEncoding);
}

JsonResult

 序列化的Json对象,将指定对象序列化为Json字符串,再调用Response.Write()将字符串写入到HTTP输出流。MVC将Response.ContentType设置为application/json,通过JavaScriptSerializer类将指定对象序列化为Json表示方式。默认情况下,MVC不允许GET请求返回Json结果,可将JsonRequestBehavior属性设置为AllowGet以解除限制。

public class JsonResult : ActionResult {
public JsonResult();
public Encoding ContentEncoding { get; set; }
public string ContentType { get; set; }
public object Data { get; set; }
// 指示是否允许来自客户端的 HTTP GET 请求
public JsonRequestBehavior JsonRequestBehavior { get; set; }
public override void ExecuteResult(ControllerContext context);
}
// 允许/拒绝支持对HTTP-GET请求的响应
public enum JsonRequestBehavior{ AllowGet, DenyGet }

 CLR对象与Json格式字符串的序列化/反序列化过程由序列化器JavaScriptSerializer来完成:

public class JavaScriptSerializer {
public int MaxJsonLength { get; set; } // Json格式字符串
public int RecursionLimit { get; set; }
public string Serialize(object obj); // 序列化
public void Serialize(object obj, StringBuilder output);
public object Deserialize(string input, Type targetType); // 反序列化
public object DeserializeObject(string input);
}

 抽象类Controller定义多个重载方法根据指定的内容、编码方式、媒体类型和JsonRequestBehavior值创建相应的JsonResult对象:

public abstract class Controller : ControllerBase, ... {
protected internal JsonResult Json(object data, xxx);
protected internal virtual JsonResult Json(object data, xxx);
}

 Json

 JavaScript Object Notation,轻量级的数据交换格式,是JavaScript的原生格式,采用完全独立于语言的文本格式,是理想的数据交换语言。Json是完全动态的,允许在Json的结构中间改变数据的表示方式。

  • 易于编写阅读、解析生成,提升网络传输速率;
  • 数据在键值对中,数据由逗号隔开,花括号保存对象,方括号保存数组;
  • Json格式和XML格式可以相互转化;

JavaScriptResult

 允许在服务端动态生成一段JS脚本用于客户端执行之,并以此作为请求的响应。ExecuteResult()方法将脚本内容写入当前HttpResponse,并将媒体类型设置为“application/x-javascript”。返回类型为JavaScriptResult的Action方法一般用于处理Ajax请求。

public class JavaScriptResult : ActionResult {
public JavaScriptResult();
public string Script { get; set; } // JS脚本
public override void ExecuteResult(ControllerContext context);
}

 抽象类Controller中定义了一个JavaScript方法根据指定的脚本字符串创建一个JavaScriptResult对象:

public abstract class Controller : ControllerBase, ... {
protected virtual JavaScriptResult JavaScript(string script);
}

ViewResult

 HTML的页面内容,用于呈现数据。由于Controller和相关Service已经处理完成业务逻辑并将结果打包成Model实体,View需要获得Model并将其转为Html。

参考: