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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM