控制器-各种ActionResult
我们所看到的Action都是return View();我们可以看作这个返回值用于解析一个aspx文件。而它的返回类型是ActionResult如
public ActionResult Index()
{
return View();
}
除了View()之外那我们这里还能用于返回什么值呢?
<1>ascx页面 分部视图 PartialViewResult
场景:要返回代码片断,比如Ajax返回一个子页
让我们先建立一个TestController.cs控制器;我们先新建一个Action
public PartialViewResult Ascx()
{
return PartialView();
}
然后给这个Action添加一个视图Ascx.cshtml
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Ascx</title>
</head>
<body>
<div>
<table border="1">
<tr><th>中国</th><th>美国</th><th>英国</th></tr>
<tr><th>湖南</th><th>纽约</th><th>巴黎</th></tr>
</table>
</div>
</body>
</html>
在浏览器中运行 http://localhost:8439/Test/Ascx 得到的结果是一个ascx页面
<2>ContentResult 返回文本
在Test控制器下添加一个Action方法
public ContentResult Text()
{
return Content("这是一段文本"); //往前台输出一个字符串
//它相当于以下两句代码:
//Response.write("这是一段文本");
//Response.End(); //End 方法使 Web 服务器停止处理脚本并返回当前结果。文件中剩余的内容将不被处理。如果 Response.Buffer 已设置为 TRUE,则调用 Response.End 将缓冲输出
}
这个连视图都不用添加
直接在浏览器中运行 http://localhost:8439/Test/Text 结果是在网页上输出“这是一段文本”这么一行字
<3.1>JsonResult 返回Json
有时我们在调用Ajax时还会要求返回对象为Json序列化的结果,如:
public JsonResult ShowJson()
{
var userinfo = new { Name = "奥巴马", Age = 56 };
return Json(userinfo, JsonRequestBehavior.AllowGet);
//var tempObj = new { Controller = "DemoController", Action = "JsonResultDemo" };
//return Json(tempObj,JsonRequestBehavior.AllowGet);
//JsonRequestBehavior.AllowGet表示:允许来自客户端的 HTTP GET 请求
//return Json(User, JsonRequestBehavior.AllowGet);
}
在浏览器中运行 http://localhost:8439/Test/ShowJson 然后就弹出一个窗体让你保存ShowJson.json文件。
保存图片后,用记事本打开文件,文件的内容是 :{"Name":"奥巴马","Age":56}
源代码:
//在Controller控制器中有一个Json方法,这个Json方法
protected internal JsonResult Json(object data)
{
return this.Json(data, null, null, JsonRequestBehavior.DenyGet);
}
//在JsonResult类中执行了ExecuteResult方法
public override void ExecuteResult(ControllerContext context)
{
//.....省略代码
HttpResponseBase response = context.HttpContext.Response;
if (!string.IsNullOrEmpty(this.ContentType))
{
response.ContentType = this.ContentType;
}
else
{
response.ContentType = "application/json"; //设定响应类型为json
}
if (this.ContentEncoding != null)
{
response.ContentEncoding = this.ContentEncoding;
}
if (this.Data != null)
{
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();//创建了一个序列化对象
if (this.MaxJsonLength.HasValue)
{
javaScriptSerializer.MaxJsonLength = this.MaxJsonLength.Value;
}
if (this.RecursionLimit.HasValue)
{
javaScriptSerializer.RecursionLimit = this.RecursionLimit.Value;
}
response.Write(javaScriptSerializer.Serialize(this.Data)); //将Data序列化成json字符串后写入到响应报文中
}
}
<3.2>返回Json
/// <summary>
/// 返回一个JSON数据
/// </summary>
/// <param name="pageIndex">当前页码</param>
/// <returns>JSON数据</returns>
public JsonResult Paging(int pageIndex)
{
//从数据库查询数据
var query = ((from a in db.T_User
where a.Id > pageIndex * 5
select a).Take(5)).ToList();
JsonResult json = new JsonResult();
json.JsonRequestBehavior = JsonRequestBehavior.AllowGet; //允许来自客户端的HTTP GET请求
json.Data = new
{
result = query, //将从数据库中查询出来的数据赋值给jsond对象。
};
return json;
}
<4>JavaScriptResult 输出JS文件
大多时候js文件都是静态的,但有时js文件可能也要动态生成这时我们可以这样输出:
public JavaScriptResult Js()
{
return JavaScript("var x=0;");
}
在浏览器中运行:http://localhost:8439/Test/Js 弹出一个窗体:如下
保存后,用记事本打开Js.js文件 内容是: var x=0;
源代码:
//在Controller控制器中有一个JavaScript方法,这个Json方法
protected internal virtual JavaScriptResult JavaScript(string script)
{
return new JavaScriptResult
{
Script = script
};
}
//在JavaScriptResult类中执行了ExecuteResult方法
public override void ExecuteResult(ControllerContext context)
{
//....省略代码
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = "application/x-javascript"; //设定响应类型为javascript
if (this.Script != null)
{
response.Write(this.Script);//将内容写入响应报文中
/*
注:这个this.Script其实就是我们在控制器JavaScript方法中写的参数
public JavaScriptResult Index()
{
return JavaScript("int a=1; alert(a)"); //就是这个"int a=1; alert(a)"
}
*/
}
}
<5>RedirectResult 页面跳转
1.跳转到Action
public RedirectResult rdaction()
{
return RedirectToAction("Text", "Test");//跳转到Test控制下的Text方法
}
在浏览器中运行:http://localhost:8439/Test/rdaction 于是立刻就跳转到 http://localhost:8439/Test/Text页面了,于是输出
2.跳转到URL
public RedirectResult rdurl()
{
return Redirect("http://www.baidu.com");
}
在浏览器中运行:http://localhost:8439/Test/rdurl 于是立刻就跳转到百度的首页了。
3.跳转到Routing规则
public RedirectResult rdrouting() //跳转到Routing规则
{
return RedirectToRoute("Default",//Route名
new
{
Controller = "Test",
Action = "Ascx"
});
}
在浏览器中运行:http://localhost:8439/Test/rdrouting 于是立刻就跳转到 Test控制器下的Ascx方法了,即跳转到http://localhost:8439/Test/Ascx 页面了
于是就输出 http://localhost:8439/Test/Ascx页面的内容
<6>FileResult 输出文件
注:表示一个用于将二进制文件内容发送到响应的基类
其实FileStreamResult继承了FileResult 而FileResult又继承了ActionResult 其实FileResult与FileStreamResult是一个东西
public FileResult fn()
{
return File("d:/123.jpg","jpg/png/JPEG");
}
在浏览器中运行:http://localhost:8439/Test/fn 弹出一个对话框:如下
点击保存后,选择用图片查看器打开。显示出了 D盘下的123.jpg图片
<7>FileStreamResult 输出文件流
注:使用 System.IO.Stream 实例将二进制内容发送到响应
FileStreamResult继承了FileResult 而FileResult又继承了ActionResult。 其实FileResult与FileStreamResult是一个东西
public FileStreamResult FileStreamResultDemo()//将d盘下的haha.jpg文件转化成一个文件流,返回到前台
{
FileStream fs = new FileStream("d:/haha.jpg", FileMode.Open, FileAccess.Read);
return File(fs, @"jpg/image/gif");//记得这个File()方法有6个重载哦。到时候可以使用以下哦。
}
运行浏览器:http://localhost:8439/Test/FileStreamResultDemo 弹出一个对话框
选择保存。保存后,选择用图片查看器打开,就显示了一幅D盘下的 haha.jpg文件
源码:
//在Controller中有个File方法,它有一个重载的返回值是FileStreamResult类型,而这个FileStreamResult是继承自FileResult
protected internal FileStreamResult File(Stream fileStream, string contentType)
{
return this.File(fileStream, contentType, null);
}
//在这个FileResult类中执行了ExecuteResult方法
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = this.ContentType;
if (!string.IsNullOrEmpty(this.FileDownloadName))
{
string headerValue = FileResult.ContentDispositionUtil.GetHeaderValue(this.FileDownloadName);
context.HttpContext.Response.AddHeader("Content-Disposition", headerValue);
}
this.WriteFile(response); //在这里调用(执行)了子类的WriteFile方法
}
//这个是子类FileStreamResult中的WriteFile方法,它重新了父类FIleResult的WriteFile抽象方法
protected override void WriteFile(HttpResponseBase response)
{
Stream outputStream = response.OutputStream;
using (this.FileStream)
{
byte[] buffer = new byte[4096];
while (true)
{
int num = this.FileStream.Read(buffer, 0, 4096);
if (num == 0)
{
break;
}
outputStream.Write(buffer, 0, num);//输出一个流
}
}
}
<8>返回一个空的页面
public EmptyResult EmptyResultDemo()
{
//仅仅用来占位,没有任何的逻辑。与return null是一样的
return new EmptyResult(); //空方法
}
在浏览器中运行 : http://localhost:8439/Test/EmptyResultDemo 得到的是一个空空如也的空白页
<9> 返回一个响应状态码
//HttpStatusCodeResult()这要是用来防盗链的。 例如:当博客园里有个哥们在博客园里发布了一个帖子,帖子里放了一个<img src="http://www.jd.con/img/1.jpg">的图片。 当用户访问博客园,浏览这个帖子的时候,浏览器解析到有这么个<img src="http://www.jd.con/img/1.jpg">的图片,于是就向京东的这个网站请求这幅图片。此时京东的服务器就做了一个判断,判断你这个请求的上一次请求URL地址是谁? 于是发现这个请求的上一个地址是http://wwww.cnblogs.com/abc.html。这个地址是博客园的地址,所以此时京东的服务就返回一个404的状态码。表示这幅图片不存在(其实是京东不想给你看,如果上一次的请求是从京东本网过来的话,图片就给你看了。)
public ActionResult HttpStatusCodeResultDemo()
{
//动态修改响应状态码。给请求返回一个404的响应
//404:资源找不到 500:服务器错误 304:缓存 302:重定向
return new HttpStatusCodeResult(404);
}
当控制器返回404的状态码的时候,执行这个视图的时候,浏览器的反应是