Controller 的工作主要負責從 View 中接收指令,然後把指令發送到相應的 Model 處理,在 Model 處理完成後就再把處理結果回傳到 View 去。 Controller 的基底是 Controller類別。 所有的 Controller 都存放在 Controllers目錄。
每一個 Controller 都包含許多 action method ,用來對應到使用者的操作行為。 這關係通常是1對1的,例如,若要提供使用者執行 CRUD 四種操作,你就必須建立 create, run, update, delete 四個 action。
Creating Controllers
By right-click the Controllers folder, you will see the Add Controller dialog box.
This tool will create a controller template. By default, this controller template will generates code with the following methods : Index, Details, Create, Edit, and Delete.
public ViewResult Details(string id)
{
Customers customers = db.Customers.Single(c => c.CustomerID == id);
return View(customers);
}
This action method would then be called based on the URL routing. By default, a call to http://mySite/customer/details/ALFKI would invoke the CustomerController.Details method and pass the customer ID (ALFKI) as a parameter. The view would then be returned as the Detail.aspx page inside the Views/Customer folder. The view would then use the Customer object sent to it to display information
Returning Different ActionResult Objects
action result classes
- ViewResult:return a webpage
- PartialViewResult:Used to send a section of a view to be rendered inside another view.
- RedirectResult:Used to redirect to another controller and action method based on a URL.
- RedirectToRouteResult:Used to redirect to another action method.
- ContentResult:Used to return a custom content type
- JsonResult:Used to return a message formatted as JSON
- JavaScriptResult:Used to return JavaScript code
- FileResult:Used to send binary output as the response.
- EmptyResult:Used to return nothing (void) as the result.
The return type for most action methods is ActionResult . The ActionResult class is actually a base class that can be used to define several different result types. Each result type does something different as a result of your action method. Possible types include :
- ViewResult:to show a webpage
- RedirectResult:to redirect to another controller.
- RedirectToRouteResult:to redirect to another action method.
You can also return simple types, such as string or integer, from your action methods. In this case, the results will be wrapped in an ActionResult object for you. Finally, you can indicate that a method inside your controller does not return an ActionResult. To do so, you mark it with the NonAction attribute to indicate that it is not an action method.
不同型態的回傳範例
//回傳一個 View
public ActionResult Index()
{
return View();
}
//回傳一個字串
public string Hello()
{
return "Hello";
}
//回傳一個 JsonResult
public JsonResult HelloJson()
{
Listtmp = new List ();
tmp.Add("Hello");
tmp.Add("World");
return this.Json(tmp, JsonRequestBehavior.AllowGet);
//["Hello","World"]
}
//回傳一個 RedirectToRouteResult
public ActionResult Edit(Customers customers)
{
if (ModelState.IsValid)
{
db.Customers.Attach(customers);
db.ObjectStateManager.ChangeObjectState(customers, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index"); // return RedirectToRouteResult type
}
return View(customers);
}
使用 jQuery 呼叫 Action Method
public JsonResult HelloJson()
{
Listtmp = new List ();
tmp.Add("Hello");
tmp.Add("World");
return this.Json(tmp, JsonRequestBehavior.AllowGet);
//["Hello","World"]
}
Passing Data to Action Methods
Action 是處理 request 的方法,那它要如何接收用戶端傳來的參數資料呢?
HTTP Get Parameters
通常要由 request 傳參數值給 action ,會以 name-value pairs 的型式傳遞。
這些資料可能來自於 form data, query string, cookie contents 等。
而且 ASP.NET MVC 會自動以 name 去對應這些 name-value 的資料與 action method 中的參數。
例如若有個 request 的格式為 http://localhost:6666/Customers/Search/customerID=ANATR&contactTitle=Owner
它就會自動對應到 Customers.Search(customerID, contactTitle) 這個 action method 。
此外,也可以透過 routing 來指定對應的參數值。 例如,若 routing 設定成 {controller}/{action}/{id},當收到像 http://mySite/customer/details/5 的需求,就會自動對應到 Customer.Details(id) 方法。
// GET: /Customers/Delete/5
// [HttpGet] 為處理需求的預設屬性
public ActionResult Delete(string id)
{
Customers customers = db.Customers.Single(c => c.CustomerID == id);
return View(customers);
}
HTTP Post Parameters
You can also call an action method as part of an HTTP post. To do so, you mark the action method with the HttpPost attribute.
In this case, you define a parameter to your action method by using the FormCollection namevalue collection. ASP.NET MVC will then map the posted form data to this collection.
public ActionResult Edit(string id) //For Editing
{
Customers customers = db.Customers.Single(c => c.CustomerID == id);
return View(customers);
}
[HttpPost]
public ActionResult Edit(Customers customers) //For Postback
{
if (ModelState.IsValid)
{
db.Customers.Attach(customers);
db.ObjectStateManager.ChangeObjectState(customers, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index"); // 若更新成功,重新導向至指定的動作
}
return View(customers); // 若更新失敗,return Edit View
}
Request and Response Data
You can also get at additional data in the request (HTTP get) or response (HTTP post). For instance, if your data is not passed or mapped to a parameter, you can use the Controller class's Request and Response properties. These properties follow the HttpRequest and HttpResponse semantics you are familiar with in ASP.NET.
//get a query string value
string name = Request.QueryString("name");
//add to the response
Response.Write("Hello World")
Passing Data to Views
有時候你想由 Controller 傳遞資料到 View 頁面之中,應該怎麼做呢?
ViewData是一個 ViewDataDictionary型別, 在 ControllerBase (for controller) 和 ViewPageBase (for view) 類別中都有這個屬性可以存取, 所以你可以透過這個屬性,由 controller 傳遞資料給 view 。
public ViewResult Index()
{
ViewData["Msg"] = "Hello world";
return View();
}
@ViewData["Msg"].ToString()
Using Action Filters
若你想在 action method 執行前或執行後加入一些邏輯判斷程式,例如,在執行前進行權限的審查,在執行後進行Log的記錄等等, 就可以使用Action Filters功能。
Action filters是一種屬性類別,都是由 Filter繼承而來。 你也可以繼承這個類別或繼承 MVC 中已定義好的 Action filters來自訂自已的 Action filters。
Action Filters 的類型
MVC 提供了四種不同介面的 action filter
- IActionFilter:Action filters 提供action額外的處理動作,例如:提供額外的資料,檢查回傳的值,或是取消action的動作。
- IResultFilter:Result filters 重新包裝Action Result,可以增加結果的額外處理,像是修改Http的Response。例如:OutputCacheAttribute。
- IAuthorizationFilter:Authorization flters 用來驗證使用者是否有權限執行
- IExceptionFilter:Exception filters 用來處理例外,指定例外發生時要執行的action,用來記錄log或是顯示錯誤訊息頁面。例如:HandleErrorAttribute。
上述提到的內建 action filter (如 Authorize 等) ,也是繼承 Filter類別,並實作這些介面。
若要自訂 action filter ,也是要繼承 Filter類別,並實作這些介面。
如何自訂 Action Filters
要自訂 Action Filters,你只要新增一個類別,並繼承自 Filter基底類別或者其衍申類別即可。參考以下範例:
public class MyActionFilter : FilterAttribute, IActionFilter, IResultFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
throw new NotImplementedException();
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
throw new NotImplementedException();
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
throw new NotImplementedException();
}
public void OnResultExecuting(ResultExecutingContext filterContext)
{
throw new NotImplementedException();
}
}
如何使用 Action Filters
使用時,只要在 action method 上頭加上 action filter 屬性即可
[MyActionFilter]
public ViewResult Index()
{
...
}
若放在 controller 上頭,表示整個控制器中的 action method 都要套用
[MyActionFilter]
public class HomeController : Controller
{
public ViewResult Index()
{
...
}
public ViewResult Index2()
{
...
}
}