Asp.Net MVCシリーズ--進級編のコントロール(1)

8970 ワード

インターフェースIControllerを実装することでコントロールを完了


デフォルトのルーティングの場合:

routes.MapRoute(
                name: "Default",
                url:"{controller}/{action}/{id}",
                defaults: new { controller ="Home", action = "Index", id = UrlParameter.Optional }
           );

 

コントロールの追加:

public void Execute(RequestContextrequestContext)
       {
           var controller = (string)requestContext.RouteData.Values["controller"];
           var action =(string)requestContext.RouteData.Values["action"];
           requestContext.HttpContext.Response.Write(
           string.Format("Controller: {0}, Action: {1}", controller,action));
 
       }

Controllerにアクセスして結果を表示します。


これは最も簡単なコントロールの作成方法ですが、通常はそうしません.
RequestContextオブジェクトを手に入れたので、手動でhtmlを生成してResponseに書き込んでクライアントに戻る必要があります.コードはメンテナンスしにくいです.
 
Controllerクラスを統合してコントロールを完了
一般的に、コントローラを新規作成するたびに、コントローラクラスを自動的に継承します.このクラスは主に2つのことを完了します.
1.ルーティングからrequestContextオブジェクトを取得し、actionおよびパラメータを解析して呼び出す
2.異なるresult(commandモード)を提供し、クライアントに返す
また、filterを使用して、異なるcrosscuttingのconcernを完了することもできます.後述します.
actionとresultの概念を導入したため、私たちのコードはユニットテストを容易にし、少なくとも私たち自身がIControllerインタフェースを継承するよりも、RequestContextオブジェクトを直接操作するのが簡単です.
 

コントローラの例:


 
public class DerivedController :Controller {
public ActionResult Index() {
ViewBag.Message = "Hellofrom the DerivedController Index method";
return View("MyView");
}
}

Viewコード:
@{
ViewBag.Title ="MyView";
}
<h2>MyView</h2>
Message: @ViewBag.Message

 
コードは簡単で、ViewbagでViewに転送して表示され、Controllerは最もよく使われるresult,ViewResultを返します.
 

コントローラからクライアントの値を取得する方法


1.context objectから直接抽出
2.パラメータによる転送(ベースクラスコントローラによる解析完了)
3.model binding経由
 

context objectでよく使われるオブジェクト


Request.QueryString
Getリクエストurlから
Request.Form
Postリクエストのフォームから
Request.Cookies
リクエストしたクッキーに値を入れて持ってきて
RouteData.Route
ルーティングテーブルから登録されたルーティング名を取得
RouteData.Values
ルーティングテーブルからルーティング構成の匿名オブジェクトを取得
HttpContext.Cache
アプリケーションキャッシュ
HttpContext.Items
同じリクエストでのみ使用できる値を格納します(httppipellineプロシージャの異なるmodule、handler、およびページ転送値)
HttpContext.Session
現在のユーザーのセッション
TempData
一時値を保存すると自動的に削除されます
 
また、RouteDataから直接使用することは推奨されない.Valuesは、送信されたパラメータ値を直接取得します.
public  ActionResult  ShowWeatherForecast() {
string city =(string)RouteData.Values["city"];
DateTime forDate =DateTime.Parse(Request.Form["forDate"]);

return View(forDate);
}

 
参照として書き換えることを推奨します.
public ActionResult ShowWeatherForecast(string city, DateTime forDate) {

return View(forDate);
}

伝参について、注意:


1.参照タイプについて、RouteDataがパラメータを取得していない場合はnullを与えます.nullを受信しないようにするには、デフォルトのパラメータを使用します.
2.値タイプについては、パラメータを取得しないと例外が放出されるため、値タイプには常にデフォルトのパラメータを指定するか、Nullableタイプを使用することを推奨します.
例:
public ActionResult Search(stringquery= "all", int page = 1) {
// ...process request...
return View();
}

Execute Resultの使用


Controllerの役割:
1.操作domain model
2.適切なresultを返す
 
domainmodelを操作した後、クライアントにresultを返します.IControllerインタフェースを手動で実現するRedirectや直接Responseはお勧めしません.Writeデータはクライアントに与えられる.前述したように、
1.htmlを直接出力したり、urlを直接ジャンプしたりして、可読性とメンテナンス性を低下させる
2.ユニットテストが難しい
3.受け渡しが難しい
 

ActionResultの使用


MVC Frameworkのcontrollerは、クライアントに戻ってインタラクションを完了するのに十分なresultタイプを与えています.ActionResultを理解するには、まずcustomizeを1つください.
public class CustomRedirectResult: ActionResult {
public string Url { get; set; }
public  override void ExecuteResult(ControllerContextcontext) {
string fullUrl =UrlHelper.GenerateContentUrl(Url, context.HttpContext);
context.HttpContext.Response.Redirect(fullUrl);
}
}

customizeを1つのresultにするには、ActionResultを継承する必要があります.主にExecuteResultメソッドを実現します.MVCFRameworkは私たちにcontrollerContextオブジェクトを与えてくれました.そこには十分な情報があります.以上に作成したactionResult機能:urlを指定し、controllerContextオブジェクトを手に入れてfullurlを生成し、ジャンプを完了します.
このresultを使用します.
public  ActionResult ProduceOutput() {
if (Server.MachineName == "IORI"){
return new CustomRedirectResult {Url = "/Basic/Index" };
} else {
Response.Write("Controller:Derived, Action: ProduceOutput");
return null;
}
}

一般的なresult:


ViewResult
異なるコントローラを指定できるviewを返します
ParcialViewResult
戻る部分view
RedirectToActionResult
別のアクションに移動
RedirectResult
は、301または302(permanent)を返します.
JsonResult
jsの最も好きなjsonを返して、よく使って、特に現在のセグメントは純粋なjs templateを採用するつもりで、あるいはsingle page application
FileResult
ファイルresult
ContentResult
文字列
HttpUnauthorizedResult
401、通常、ログインページに自動的にジャンプします
HttpNotFoundResult
404
 

viewResultに戻ると、検索順序:


1.      /Views//.aspx
2.      /Views//.ascx
3.      /Views/Shared/.aspx
4.      /Views/Shared/.ascx
5.      /Views//.cshtml
6.      /Views//.vbhtml
7.      /Views/Shared/.cshtml
8.      /Views/Shared/.vbhtml
mvcframeworkはまずよく知っているaspxとascxから探します
 

パスを直接渡し、指定したviewに戻る

public ViewResult Index() {
return View("~/Views/Other/Index.cshtml");
}

上記のようなコードが表示された場合は、次の2つの問題について考えてください.
別のアクションにジャンプしたいですか?RedirectToActionの使用も考えられます
Viewは位置を間違えましたか?
 

ActionをViewに転送


Model Object

public ViewResult Index() {
DateTime date = DateTime.Now;
return View(date);
}

 
View:
@model DateTime
@{
ViewBag.Title ="Index";
}
<h2>Index</h2>
The day is: @Model.DayOfWeek

 

ViewBag

public ViewResult Index() {
ViewBag.Message ="Hello";
ViewBag.Date = DateTime.Now;
return View();
}

View:
@{
ViewBag.Title ="Index";
}
<h2>Index</h2>
The day is:@ViewBag.Date.DayOfWeek
<p />
The message is: @ViewBag.Message

ViewBagの利点:
タイプを定義せずに直接渡すことができ、任意のオブジェクトを渡すことができます.
欠点:
エラーは常に実行されます.DynamicObjectです(実際にはDynamicViewDataDictionaryはDynamicObjectから継承されているため、他のfunctionlanguage言語のように動的に拡張できます).
 

指定urlにリダイレクト


HttpStatusCode:302(一時リダイレクト)

public RedirectResult Redirect(){
return Redirect("/Example/Index");
}

HttpStatusCode:301(永久リダイレクト、使用注意、非常用)

public RedirectResult Redirect(){
return RedirectPermanent("/Example/Index");
}

routeに戻る

public RedirectToRouteResult Redirect() {
return RedirectToRoute(new {
controller = "Example",
action = "Index",
ID = "MyID"
});
}

ほとんどの場合、処理できないリクエストに遭遇した場合、少なくともどのコントローラとactionにジャンプするかを決定することができます.
public  RedirectToRouteResult  RedirectToRoute() {
return RedirectToAction("Index");
}

コントロールを指定できます.
public RedirectToRouteResult Redirect() {
return RedirectToAction("Index", "Basic");
}

Redirectionプロセスで値を渡す


MVCframeworkでは、TempDataを使用することが望ましい.
割り当て:
public  RedirectToRouteResult  RedirectToRoute() {
TempData["Message"] ="Hello";
TempData["Date"] =DateTime.Now;
return RedirectToAction("Index");
}

値:
public ViewResult Index() {
ViewBag.Message =TempData["Message"];
ViewBag.Date =TempData["Date"];
return View();
}

このオブジェクトの利点は、取り終わったらremovableとマークされ、リクエストが終わったら自動的にクリアされることです.何度も取りたい場合はpeekメソッドを使用します(ただし、最後にクリアした(インデックスで取る)ことをお勧めします):
TempData.Peek("Date");
また筆者はHttpRequestを推薦する.Itemsも、httppipeline内で値を伝える良い選択です.
 
 

httpstatus codeを返します


 
404(urlが見つかりません):
public HttpStatusCodeResult StatusCode() {
return new HttpStatusCodeResult(404, "URL cannot be serviced");
}

 
401(アクセス制限):
public HttpStatusCodeResult StatusCode() {
return new HttpUnauthorizedResult();
}