ASP.NET MVC系列:Controller/Action

1. Controller

  Controller是ASP.NET MVC的核心,负责处理浏览器请求,并作出响应。Cotroller本身是一个类(Class),该类有多个方法(Method)。在这些方法中,只要是公开方法,该方法将被视为一个动作(Action);只要有动作存在,就可以通过该动作方法接收网页请求并决定应响应的视图。

1.1 Controller的基本要求:

  ◊ Controller必须是公共(Public)类;

  ◊ Controller的名称必须以“Controller”结尾;

  ◊ 必须继承ASP.NET MVC的Controller类,或继承实现IController接口的自定义类,或自身实现IController接口;

  ◊ 所有方法必须为Public方法。该方法可以没有参数,也可以有多个参数。

2. Action名称选择器

  当通过ActionInvoker选取Controller中的公共方法时,默认会用Reflection方式取得Controller中具有相同名称的方法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// http://localhost/Home/Index
        /// </summary>
        public ActionResult Index()
        {
            return View();
        }
    }
}

  可以通过在Action上使用ActionName属性(Attribute)来指定Action,这就是动作名称选择器(Action Name Selector)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// http://localhost/Home/Default
        /// </summary>
        [ActionName("Default")]
        public ActionResult Index()
        {
            return View();
        }
    }
}

3. 动作方法选择器

  在通过ActionInvoker选取Controller中的公共方法是,ASP.NET MVC还提供了一个特性,动作方法选择器(Action Method Selector),以帮助ActionInvoker选择适当的Action。

3.1 NonAction属性

  若将NonAction属性应用在Controller中的Action方法上,即使该Action方法是公共方法,也会告知ActionInvoker不要选取这个Action来执行。这个属性主要用来保护Controller中的特定公共方法不会发布到Web上。或是当功能尚未开发完成就要进行部署时,若暂时不想将此方法删除,也可以使用这个属性。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        [NonAction]
        public ActionResult Index()
        {
            return View();
        }
    }
}

  将Action方法的“public”改成“private”,也可以达到同样的目的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        private ActionResult Index()
        {
            return View();
        }
    }
}

3.2 HttpGet属性、HttpPost属性、HttpDelete属性和HttpInput属性

  HttpGet、HttpPost、HttpDelete、HttpInput属性是动作方法选取器的一部分,这些属性常用在需要接收窗口数据的时候。如:创建两个同名的Action,一个应用[HttpGet]属性来显示窗口HTML,另一个应用[HttpPost]属性来接收窗口发送的值。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Libing.Portal.Web.Models;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public ActionResult Create()
        {
            return View();
        }

        public ActionResult Create(Product product)
        {
            //UpdateModel(product);
            return RedirectToAction("Index");
        }
    }
}

4. ActionResult类

  ActionResult类是Action执行的结果,但ActionResult中并不包含执行结果,而是包含执行响应时所需要的信息。当Action返回ActionResult类之后,会由ASP.NET MVC执行。

  ASP.NET MVC定义的ActionResult如下表所示:

Controller辅助方法用途
ContentResult Content 返回一段用户自定义的文字内容
EmptyResult   不返回任何数据,即不响应任何数据
JsonResult Json 将数据序列转化成JSON格式返回
RedirectResult Redirect 重定向到指定的URL
RedirectToRouteResult RedirectToAction、RedirectToRoute 重定向到Action或Route
ViewResult View 使用IViewInstance接口和IViewEngine接口,实际输出的数据是IViewEngine接口和View
PartialViewResult PartialView 与ViewResult类相似,返回的是“部分显示”
FileResult File 以二进制串流的方式返回一个文件数据
JavaScriptResult JavaScript 返回JavaScript指令码

  以上的动作结果都继承自ActionResult基类。

4.1 ViewResult

  ViewResult类是在ASP.NET MVC中最常用的ActionResult类,用于返回一个标准的视图。通过Controller辅助方法,可以定义输出的View名称。

4.1.1 返回默认的页面

  返回的默认页面与Action的名称相同

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
}
public ViewResult Index()
{
    return View();
}

4.1.2 指定页面名称的响应

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View("Default");
        }
    }
}

4.1.3 指定的页面不存在

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
       public ActionResult Index()
       {
           return View("NotExists");
       }
    }
}

  当在Views目录下找不到页面时,出现下面的提示信息。

4.2 PartialViewResult

  PartialViewResult与ViewResult非常相似,通过用在前端为Ajax应用程序的情况下,并可以通过Ajax来取得网页中的部分内容。

public ActionResult About()
{
    return PartialView();
}

4.3 EmptyResult

  有一些Action在执行后其实不需要返回任何数据,例如一个页面执行完后直接转到其他页面的情况。EmptyResult不会执行任何响应客户端的程序,所以也不会返回任何数据。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Empty()
        {
            return new EmptyResult();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        public void Empty()
        {
            return;
        }
    }
}
public EmptyResult Index()
{
    return new EmptyResult();
}

  使用EmptyResult与Response.RedirectPermanent()进行HTTP301跳转

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        public void Redirect()
        {
            Response.RedirectPermanent("/Home/Index");
        }
    }
}
public RedirectResult About()
{
    return Redirect("/Home/Index");
}

4.4 ContentResult

  ContentResult类可以响应文字内容的结果。可以让ContentResult类响应任意指定文字内容、Content-Type和文字编码(Encoding)。

  示例响应一段XML文字,并设定响应的Content-Type为text/xml,文本编码格式为Encoding.UTF8.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Content()
        {
            return Content("<root><text>123</text></root>", "text/xml", System.Text.Encoding.UTF8);
        }
    }
}

  响应HTML字符串

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Content()
        {
            string strHTML = "<h1>123</h1>";
            return Content(strHTML);
        }
    }
}

  ASP.NET MVC会进行判断,只要Action返回的不是ActionResult类,就会将返回的类转换成字符串输出。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Libing.Portal.Web.Controllers
{
    public class HomeController : Controller
    {
        public string Content()
        {
            string strHTML = "<h1>123</h1>";
            return strHTML;
        }
    }
}

6.5 FileResult

  FileResult类可以响应任意的文件内容,包括二进制格式的数据,可以输入byte[]、文件路径、Stream数据、Content-Type、下载文件名等参数并将其返回客户端。

  FileResult是一个抽象类,在ASP.NET MVC中实现FileResult类的子类包括:

  ◊ FilePathResult:响应一个实体文件;

  ◊ FileContentResult:响应一个byte[]的内容;

  ◊ FileStreamResult:响应一个Stream数据。

  示例:FilePathResult

public ActionResult Download()
{
    return File(Server.MapPath("~/Content/Logo.png"), "image/png");
}

  示例:FileContentResult

public ActionResult Download()
{
    FileStream fs = new FileStream(Server.MapPath("~/Content/Logo.png"), FileMode.Open, FileAccess.Read);
    byte[] fileContent = new byte[Convert.ToInt32(fs.Length)];
    fs.Read(fileContent, 0, Convert.ToInt32(fs.Length));

    return File(fileContent, "image/png");
}

  示例:FileStreamResult

public ActionResult Download()
{
    FileStream fs = new FileStream(Server.MapPath("~/Content/Logo.png"), FileMode.Open, FileAccess.Read);

    return File(fs, "image/png");
}

  示例:pdf文件

public ActionResult Download()
{
    FileStream fs = new FileStream(Server.MapPath("~/Content/Report.pdf"), FileMode.Open, FileAccess.Read);
    byte[] fileContent = new byte[Convert.ToInt32(fs.Length)];
    fs.Read(fileContent, 0, Convert.ToInt32(fs.Length));

    return File(fileContent, "application/pdf", "Report.pdf");
}

  示例:中文名称文件

public ActionResult Download()
{
    FileStream fs = new FileStream(Server.MapPath("~/Content/Report.txt"), FileMode.Open, FileAccess.Read);
    byte[] fileContent = new byte[Convert.ToInt32(fs.Length)];
    fs.Read(fileContent, 0, Convert.ToInt32(fs.Length));

    return File(fileContent, "text/plain", Server.UrlPathEncode("报表.txt"));
}

6.6 JavaScriptResult

  JavaScriptResult类的用途是将JavaScript代码响应给浏览器。通过Ajax利用JavaScriptResult类来响应当前的JavaScript程序代码并将其提交到浏览器动态执行。

  JavaScriptResult类的功能与ContentResult类主要差别在于JavaScriptResult类的默认Content-Type为application/x-javascript。

public ActionResult RunJavaScript()
{
    return JavaScript("alert('运行JavaScript')");
}
@Ajax.ActionLink("测试JavaScript", "RunJavaScript", new AjaxOptions())

6.7 JsonResult

  JSON(JavaScript Object Notation)是Web实现Ajax应用程序时经常使用的一种数据传输格式,JsonResult可以自动将任意对象的数据序列转换成JSON格式返回。JsonResult默认的Content-Type是application/json。

  JsonResult使用JavaScriptSerializer完成JSON序列化,如果对象无法序列化,转换过程也会发生意外。为了避免JSON Hijacking攻击,ASP.NET MVC基于安全考虑,设置在默认情况下,任何以JsonResult类返回的请求都不允许GET方法从中获取JSON数据。要JsonResult对HTTP GET请求进行响应,需Json()方法设置JsonRequestBehavior.AllowGet。

  示例:Json()默认

public ActionResult GetList()
{
    List<Product> products = new List<Product>();
    products.Add(new Product
    {
        ProductID = 1,
        ProductName = "ASP.NET MVC"
    });

    return Json(new
    {
        root = products,
        totalProperty = products.Count
    });
}
<script type="text/javascript">
    $(function () {
        $.post("@Url.Action("GetList","Home")",
            function (data) {
                console.log(data.totalProperty);
            },
            "json"
        );
    });
</script>

  示例:Json() AllowGet

public ActionResult GetList()
{
    List<Product> products = new List<Product>();
    products.Add(new Product
    {
        ProductID = 1,
        ProductName = "ASP.NET MVC"
    });

    return Json(new
    {
        root = products,
        totalProperty = products.Count
    }, JsonRequestBehavior.AllowGet);
}
<script type="text/javascript">
    $(function () {
        $.get("@Url.Action("GetList","Home")",
            function (data) {
                console.log(data.totalProperty);
            },
            "json"
        );
    });
</script>

6.8 RedirectResult

  RedirectResult主要用于执行指向其他页面的重定向。

  Redirect()方法定义:

protected internal virtual RedirectResult Redirect(string url);

  示例:

public ActionResult Redirect()
{
    return Redirect("/Home/Index");
}

6.9 RedirectToRoute

  Controller类中有两个与RedirectToRoute类有关的辅助方法:RedirectToAction()和RedirectToRoute()。

6.9.1 RedirectToAction

  1>. 原型定义

protected internal RedirectToRouteResult RedirectToAction(string actionName);
protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName);
protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName, object routeValues);
protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues);

  2>. 示例

public ActionResult About()
{
    return RedirectToAction("Index");
}
return RedirectToAction("Index", "Home");
return RedirectToAction("List", "Home", new { page = 2 });
return RedirectToAction("Details", new { id = product.ProductID });

6.9.2 RedirectToRoute

  1>. 原型定义

protected internal RedirectToRouteResult RedirectToRoute(object routeValues);
protected internal RedirectToRouteResult RedirectToRoute(string routeName);
protected internal RedirectToRouteResult RedirectToRoute(string routeName, object routeValues);

  2>. 示例

public ActionResult About()
{
    return RedirectToRoute(new { action = "Index" });
}
return RedirectToRoute(new { controller = "Home", action = "Index" });
return RedirectToRoute(new { controller = "Home", action = "Index", page = 2 });
posted @ 2012-04-09 20:32  libingql  阅读(6535)  评论(0编辑  收藏  举报