MS_ASPNETMVCTerms - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

ASP.NET MVCの甚語

抂芁

MVC

「ASP.NET MVCの甚語」は
「ASP.NET MVCの利甚方法」ず比べお、
ASP.NET MVC の基本的なトピックをたずめおいたす。

補足本ペヌゞの前提最新化: 本ペヌゞが扱うのは
.NET Framework 版の ASP.NET MVC 5System.Web.Mvcである。
ASP.NET Core MVC ずは別実装で、
抂念は共通だが API 名や既定動䜜が異なる箇所がある。

䞻な察応関係詳现は各節の補足で述べる:

本ペヌゞASP.NET MVC 5 ASP.NET Core MVC
ActionResult IActionResult
Html.TextBoxFor 等 タグ ヘルパヌasp-for
Ajax.BeginForm 廃止郚分描画ずJavaScript
RouteConfig.RegisterRoutes app.MapControllerRoute
Bind 属性 [Bind]健圚DTO 分離が掚奚
HandleError 属性 䟋倖ミドルりェア
Global.asax Program.cs

MModelに実装される凊理

Model には、

  • B 局クラスず、
  • B 局クラスが返す View に枡される Entity, Bean, POCO 的なクラスViewModel

がある。

VViewに実装される凊理

View  画面衚瀺のための凊理。

  • マスタペヌゞ的な View ず、
  • 党䜓 View
  • 郚分 View がある。

CControllerに実装される凊理

  • Action Method を実装する。
  • Action Method は、
    1. 「MModel」を呌び出しお
    2. 「Bean ≒ M」を取埗しお
    3. 「VView」呌び出す。

モゞュヌルの䜜成順

  1. CControllerを䜜成
  2. VViewを䜜成
  3. MModelを䜜成
  4. CControllerに Action Method を远加し、C→M→V ず繋げる。

CController関連

URL ルヌティング

ルヌト定矩

  • ルヌト定矩に埓い、URL から Controller や Action Method に凊理を振り分ける。
  • ナヌザがブラりザに URL を入力するず、
    指定したルヌティング芏則を䜿甚し、URL が解析され、Controller のパスが特定される。

既定のルヌト定矩

  • 既定のルヌト定矩は、RouteConfig.RegisterRoutes メ゜ッドで定矩されおいる。
  • ココで MapRoute() メ゜ッドを䜿甚し、ルヌトパラメタrouteName, routeValuesを登録する。
  • ルヌトパラメタrouteName, routeValuesは、URL の䜜成にも䜿甚される。
  • デフォルトでは以䞋のようにルヌト定矩されおいる(自由にカスタマむズ可胜)
routes.MapRoute(
    "Default",                     // Route name
    "{controller}/{action}/{id}",  // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

属性ルヌティングによるルヌト定矩

  • 個別のルヌト定矩は、RouteConfig.RegisterRoutes メ゜ッドで定矩されおいる。
  • ココで MapMvcAttributeRoutes() メ゜ッドを䜿甚し、属性ルヌティングを有効化する。
routes.MapMvcAttributeRoutes();
  • 以䞋のようにルヌト定矩可胜(自由にカスタマむズ可胜)
[Route("{controller}/{action}/{id}", Name="xxxx")]
  • 第䞀匕数には、MapRoute の「URL with parameters」ず同じものを指定。

  • 第二匕数の Name はオプションで、Html ヘルパヌ@Html.RouteLinkで䜿甚できる。

  • たた、パラメタに぀いお、以䞋の様な蚭定を行うこずができる。

    • オプション蚭定
    • 既定倀の蚭定
    • 制玄条件の蚭定
      • デヌタ型指定
      • 倀範囲指定
      • 正芏衚珟指定
      • カスタム制玄条件指定
  • その他、モデルレベルに既定の ActionMethod 名を远加可胜。

[Route("{action=Top}")]
public class XXXXXController : Controller
{
    public ActionResult Top() { ・・・ }
}

移行メモ誀蚘: 原文の [Route("{action=Top")] は
閉じ波括匧が欠けおいるため、[Route("{action=Top}")] に修正した。

ルヌトプレフィックスの定矩

ルヌトプレフィックスを䜿甚するず、モデルレベルに、
「URL with parameters」のルヌト郚分の定矩を远加できる。

補足ASP.NET Core での曞き方: 属性ルヌティングは
ASP.NET Core MVC でも同じ考え方で䜿える
むしろ API では属性ルヌティングが暙準。

[ApiController]
[Route("api/[controller]")]          // ルヌト プレフィックス
public class ProductsController : ControllerBase
{
    [HttpGet("{id:int}")]            // GET api/products/1
    public IActionResult Get(int id) => Ok();
}

Program.cs 偎の芏玄ルヌティングは次の圢になる。

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

**{id?}省略可胜や {id:int}型制玄**ずいった
むンラむン制玄が䜿えるため、
原文が挙げる「制玄条件の蚭定」を属性の䞭で完結しお曞ける。

呌び出される Action Method ずその匕数

この時、ブラりザから

http://server/applicationname/Products/Index/1

ずいう URL でリク゚ストを送信した堎合、

http://(Server FQDN名)/(Controller名)/(Action Method名)/(id 倀)

ルヌト定矩に埓い、ペヌゞハンドラは

  • Controller 名Products
  • Action Method 名Index
  • id (Action Method に枡す倀)1

ず刀断し、

Products Controller の Index Action Method を呌び出し、
Action Method の匕数ずしお "1" を枡す。
Action Method 名ず id 倀は省略可胜で、Action Method 名を省略するず、
Index Action Method が実行される。

Action Method

リク゚ストデヌタの取埗方法

  • 匕数ずのマップの方法

    • 単方向バむンディング
      POST や GET のパラメタの名前ず䞀臎した匕数を定矩しおおけば、自動的にマップされる。

      • Get ならク゚リ文字列のキヌ名
      • Post ならフォヌムデヌタのキヌ名
      • モデルバむンディング
        Model クラスを䜿うこずもできるProperty 名ず䞀臎させる。
    • 双方向バむンディング

      • Controller の ActionMethod ず View の間に、
        ポストバック的な埩元動䜜がある堎合に䟿利。
      • Model クラスを䜿うPost の堎合のみ。
  • その他

    • FormCollection を䜿う (Post の堎合のみ)
      <form> の䞭身がコレクション型ずしお保持されたもの。

戻り倀

Action Method の結果ずしお、Action Result を返す。
詳现はAction Resultを参照。

単方向バむンディング

  • クラむアントから送信されおきたデヌタのキヌ名ず、
    Controller の Action Method の匕数名ずが䞀臎するキヌ倀を探しお、バむンドする。

  • 非垞に単玔な仕組みのため、ASP.NET Web Formsに比べお、
    単䜓テストが遣り易くなっおいる反面、オヌバヌポスティング攻撃を受け易く、
    セキュリティ的に脆匱ずたでは蚀えないが、課題があるず蚀える。

  • 仕組みの詳现は、䞋蚘を参照。

補足オヌバヌポスティング攻撃ずは: 原文が繰り返し譊告しおいる
この攻撃は、モデル バむンディングが「送られおきた項目を玠盎に埋める」
こずに起因する。

【画面】       名前・メヌルアドレスの入力欄のみ
【モデル】     class User { Name; Email; IsAdmin; }

攻撃者が POST に IsAdmin=true を远加しお送る
  → モデル バむンダヌが玠盎に IsAdmin にも倀を入れる
  → そのたた保存するず暩限昇栌

ASP.NET Web Forms では起きにくいのは、
ViewState で「画面に出した項目」が固定されおいるためである
原文が「Web Forms に比べお」ず曞いおいるのはこの察比。

察策の優先順䜍:

察策 評䟡
① 画面専甚の ViewModelDTOを䜿う 最善。危険な項目がそもそも無い
② [Bind(Include=...)] で明瀺 有効だが、項目远加時に挏れやすい
③ [Bind(Exclude=...)] 危険陀倖挏れが起きる
④ 保存前に手で詰め替える 有効

゚ンティティをそのたた Action Method の匕数にしない、
ずいうのが珟圚の定石である。
ASP.NET Core でも同じ問題は残っおいる。

ValueProvider

Request を怜玢しお Value を取埗するクラス。

  • 既定の ValueProvider
項番 ValueProvider 倀取埗元
 ChildActionValueProvider 子アクション
 FormValueProvider フォヌム倀
 RouteDataValueProvider Route デヌタ
 QueryStringValueProvider ク゚リ文字列
 HttpFileCollectionValueProvider HTTP ファむルのコレクション
  • その他の ValueProvider
項番 ValueProvider 倀取埗元
 JsonValueProvider Json
 CookieValueProvider Cookie
 SessionValueProvider Session
 ServerVariablesValueProvider ServerVariables
 TempDataValueProviderFactory TempData

移行メモ衚蚘: 原文の「ValuProvider」は
ValueProvider の衚蚘揺れず刀断し統䞀した。

  • ValueProvider の凊理順
    䞊蚘の既定の ValueProvider は Controller.ValueProvider の順番ず同じ
    同じキヌ名の堎合、ValueProvider の順に先勝になる

  • ValueProvider の远加
    以䞋の ValueProviderFactory で順に新芏 ValueProvider を远加できる。

    • 実装Global.Application_Start に実装
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
ValueProviderFactories.Factories.Add(new CookieValueProviderFactory());
ValueProviderFactories.Factories.Add(new SessionValueProviderFactory());
ValueProviderFactories.Factories.Add(new ServerVariablesValueProvider());
ValueProviderFactories.Factories.Add(new TempDataValueProviderFactory());
  • 参考

  • カスタム ValueProvider の自䜜
    カスタムの ValueProvider を実装するために以䞋の I/F を䜿甚する。

    • IValueProvider倀プロバむダヌに必芁なメ゜ッドを定矩
    • IEnumerableValueProvider列挙に必芁なメ゜ッドを定矩
    • IUnvalidatedValueProvider怜蚌スキップに必芁なメ゜ッドを定矩

補足「先勝ち」が事故のもずになる: 同じ名前のキヌが
フォヌムずク゚リ文字列の䞡方にある堎合、
䞊衚の順Form が先で決たる。

POST /Edit?id=1   ク゚リ文字列に id=1
Body: id=99       フォヌムにも id=99
  → FormValueProvider が先なので 99 が採甚される

どこから取るかを明瀺するのが安党である。

// ASP.NET MVC 5
public ActionResult Edit([FromUri] int id, MyModel model) { }

// ASP.NET Core属性が敎理されおいる
public IActionResult Edit([FromRoute] int id, [FromForm] MyModel model) { }

ASP.NET Core のバむンド元属性:

属性 取埗元
[FromRoute] ルヌト パラメヌタ
[FromQuery] ク゚リ文字列
[FromForm] フォヌム
[FromBody] リク゚スト本文JSON
[FromHeader] ヘッダヌ
[FromServices] DI コンテナヌASP.NET Core における DI

[ApiController] を付けるず、これらが芏玄で自動掚論される
耇合型は [FromBody]、単玔型は [FromQuery] 等。

ModelBinder

  • ModelBinder は、ValueProvider から必芁なデヌタを取埗し、
    Model に察しお倀の蚭定を行う。

  • DefaultModelBinder は、前述の「既定の ValueProvider」から必芁なデヌタを怜玢する。

  • カスタム ModelBinder の自䜜も可胜。

ModelBinder 属性

前述の ModelBinder の動䜜を制埡する。

通垞、

  • コレクション系は Form
  • プリミティブ型は QueryString

から取埗するようになっおいるが、

以䞋の属性を Action Method の匕数に察しお䜿甚するず、この動䜜を倉曎できる。

  • FromUri 属性
    QueryString から倀を取埗するように制埡。

  • FromBody 属性
    Form から倀を取埗するように制埡。

移行メモFromBody の説明: 原文は
「FromBody 属性Form から倀を取埗するように制埡」ずしおいるが、
正確には [FromBody] は「リク゚スト本文JSON / XML 等から取埗する」
ずいう意味であるWeb API 由来の属性。
フォヌム デヌタの取埗は既定の動䜜であり、
ASP.NET Core では [FromForm] が別途甚意されおいる。

Bind 属性

ASP.NET MVCは、ASP.NET Web Formsず比べお、
オヌバヌポスティング攻撃を受け易いため匕数を明蚘する仕組み。

  • 基瀎

    • Bind 属性の匕数

    • 蚭定方法
      Action Methodに以䞋の様な属性を付䞎する。

      • [Bind(Include = "PropName1, PropName2...")]
      • [Bind(Exclude = "PropName3, PropName4...")]
      • [Bind(Include = "PropName1, PropName2...", Exclude = "PropName3, PropName4...")]
  • 応甚コレクションを Bind するずきの name or key の蚭定方法
    http://qiita.com/kazuhisam3/items/94542f6d7ccf3acca41c

    • 配列 or リスト系
      • VariableName[n].PropertyName
      • [n].PropertyName
    • Dictionary ç³» :
      • VariableName[n].Key, VariableName[n].Value.PropertyName
      • [n].Key, [n].Value.PropertyName

補足ASP.NET Core では Include が無くなった: [Bind] は
ASP.NET Core にもあるが、匕数の圢が倉わっおいる。

// ASP.NET MVC 5
public ActionResult Create([Bind(Include = "Name,Email")] User user)

// ASP.NET Coreプロパティ名を盎接列挙。Exclude は無い
public IActionResult Create([Bind("Name,Email")] User user)

Exclude が廃止されたのは、
**「陀倖方匏は挏れる」**ずいう前述の理由による。
ホワむトリスト列挙のみが残された、ず読める。

なお、掚奚は䟝然ずしお ViewModelDTOの分離である。

参考

双方向バむンディング

  • Controller の ActionMethod ず View の間に、ポストバック的な埩元動䜜がある堎合に䟿利。
  • Model クラスを䜿うPost の堎合のみ。

@model で定矩した Model プロパティず、

のHtml ヘルパヌを䜿甚する。

双方向バむンディングの方法

以䞋のように双方向バむンドする。

  • Controller
return View(vm);
  • View スクリプト
@model ViewModel
・・・
Html.TextBoxFor(model => model.Category) 

通垞、Model プロパティは、Model でアクセスするが、
ここでの model はラムダ匏の仮匕数名なので自由。

移行メモ衚蚘: 原文の @Model ViewModel は
**ディレクティブずしおは @model小文字**が正しい
@Model は「Model プロパティ」を指す。
原文自身がModel プロパティの節で
@model ViewModelClass ず曞いおいるため、
こちらを正ずしお統䞀した。
たた Html.TextBoxFor?(...) の ? は入力誀りず刀断し削陀した。

Xxxxx ず XxxxxForの違い

  • XxxxxFor メ゜ッドは、モデルバむンディングに察応する

    • 芁玠名id, name 属性を自動で蚭定するため、
    • 芁玠名id, name 属性を指定する匕数が無い。
  • 参考

Action Result

Controller の Action Method は、View の遞択ず指瀺ずしお、
ActionResult クラスの
オブゞェクトを返す必芁がある。

Action Method で、

return View();

ず、View を指定しない overload で呌び出すず、

/Views/コントロヌラ名/アクション名.cshtml

を呌び出す。

ActionResult の皮類ずヘルパヌ・メ゜ッド

ActionResult クラスには、以䞋の皮類が存圚する。

項番 皮類 抂芁・甚途 コヌド䟋ヘルパヌ・メ゜ッド
 ViewResult 指定された党䜓 View の衚瀺を指瀺する。
基本的には HTML.BeginForm の堎合に䜿甚する。
return View("Result");
("Result" は党䜓 View 名)
 PartialViewResult 指定された郚分 View の衚瀺を指瀺する。
基本的には Ajax.BeginForm の堎合に䜿甚する。
return PartialView("Result");
("Result" は郚分 View 名)
 RedirectResult 指定した URL にリダむレクトする堎合に䜿甚する。 return Redirect("http://www.wings.msn.to/");
 RedirectToActionResult 指定した Controller, Action にリダむレクトする堎合に䜿甚する。 return RedirectToAction("Index");
 RedirectToActionResult 指定したルヌトパラメタrouteName, routeValuesにリダむレクトする堎合に䜿甚する。 return RedirectToRoute("View Product", new { ProductName = <商品名> });
 FilePathResult 指定されたパスの内容をファむルずしお出力 return File(@"C:\temp\file.zip", "application/zip", "file.zip");
 FileContentResult byte 配列の内容をファむルずしお出力 return File(bytes, "application/pdf");
 FileStreamResult ストリヌムの内容をファむルずしお出力 return new FileStreamResult(fileStream, "application/pdf");
 ContentResult プレヌン・テキストを出力CSV 出力等 return Content("こんにちは、䞖界", "text/plain");
10 JsonResult 指定されたコンテンツを JSON ずしお出力Ajax 通信 return Json(JsonConvert.SerializeObject(result), JsonRequestBehavior.AllowGet);
11 JavaScriptResult 指定されたコンテンツを JavaScript スクリプトずしお出力 return JavaScript(code);
12 EmptyResult 䜕もしない 

移行メモ衚の展開: 原文は 5 行目の「皮類」列を
PukiWiki のセル結合~で 4 行目ず共有しおいたが、
GitHub Markdown にセル結合が無いため同じ倀を展開した。
たた "C:\temp\file.zip" は C# のリテラルずしお䞍正なので
@"C:\temp\file.zip" に修正した。

補足ASP.NET Core での戻り倀: ASP.NET Core では
IActionResult が基本で、ActionResult<T> も䜿える。

// 型を明瀺できるSwagger 生成にも効く
public ActionResult<Product> Get(int id)
    => _repo.Find(id) is { } p ? p : NotFound();

JSON の返し方が簡朔になっおいる点も違いである。

// ASP.NET MVC 5JsonRequestBehavior が必芁だった
return Json(obj, JsonRequestBehavior.AllowGet);

// ASP.NET CoreGET でも普通に返せる
return Ok(obj);        // たたは return obj;[ApiController] 時

JsonRequestBehavior.AllowGet が䞍芁になったのは、
か぀おの JSON ハむゞャック察策が
珟圚のブラりザでは䞍芁になったためである。

なお、原文の䟋が JsonConvert.SerializeObject を枡しおいるのは
二重シリアラむズになるため泚意が芁る
Json() 自䜓がシリアラむズするので、オブゞェクトをそのたた枡す。

HttpStatusCodeResult

View ではなく、HTTP 状態コヌドを返す。

項番 皮類 抂芁・甚途 コヌド䟋ヘルパヌ・メ゜ッド
 HttpStatusCodeResult 任意の HTTP 応答コヌドをセット 
 HttpUnauthorizedResult HTTP 応答コヌド「401 Unauthorized」をセット 
 HttpNotFoundResult HTTP 応答コヌド「404 NotFound」をセット 

ActionResult の自䜜

可胜

属性

フィルタ属性

  • フィルタ属性は、ActionMethod に、以䞋の様な共通的な凊理を远加するために䜿甚する。

    • 認蚌凊理
    • 䟋倖凊理
    • ロギング
    • , etc.
  • フィルタ属性は、以䞋に蚭定可胜である。

項番 適甚範囲 蚭眮堎所 説明
 ActionMethod Filter ActionMethod ActionMethod 単䜍
 Controller Filter Controller Controller 単䜍
 Global Filter FilterConfig Application 単䜍
  • 以䞋のフィルタ属性分類があり、実装される凊理は項番の順番に呌び出される。
項番 分類 実装する I/F 実装する凊理
 認蚌 IAuthenticationFilter 認蚌に関係する凊理
 承認 IAuthorizationFilter 承認認可に関係する凊理
 Action IActionFilter ActionMethod の開始凊理の前埌凊理
 Result IResultFilter ActionMethod の終了凊理の前埌凊理
 䟋倖 IExceptionFilter 䟋倖凊理
 Override IOverrideFilter 䞊䜍フィルタを䞊曞き
  • 暙準のフィルタ属性には以䞋の様なものがある。
項番 分類 属性 抂芁
 承認 Authorize 属性 認蚌枈みアクセスCookie 認蚌、Token 認蚌
 承認 ChildActionOnly属性 子アクションずしおのみ呌び出し可胜に蚭定
 承認 RequireHttps 属性 HTTPS アクセスのみ呌び出し可胜に蚭定
 承認 ValidateInput 属性 XSS 察策に䜿甚する。
 承認 ValidateAntiForgeryToken 属性 CSRF 察策に䜿甚する。
 䟋倖 HandleError 属性 <customErrors mode="On or RemoteOnly"/>
 FilterConfig に蚭定した時のカスタム゚ラヌペヌゞの定矩
 Action/䟋倖/Result OutputCache 属性 出力キャッシュルヌルの定矩
 Action/Result AsyncTimeout 属性 非同期凊理のタむムアりトの定矩
 Override OverrideAuthentication 属性 グロヌバル・モデルなど䞊䜍で定矩されたフィルタを䞊曞き
 Override OverrideAuthorization 属性 同䞊
 Override OverrideAction 属性 同䞊
 Override OverrideResult 属性 同䞊
 Override OverrideException 属性 同䞊

移行メモ衚の展開: 項番 9 の Override ç³» 5 行は、
原文ではセル結合~で項番・分類・抂芁を共有しおいたため、
倀を展開しお掲茉した。

補足ASP.NET Core のフィルタヌずミドルりェアの䜿い分け: 抂念は
ほがそのたた匕き継がれおいるが、ミドルりェアずいう遞択肢が増えた
HttpApplicationGlobal.asax、HttpModule、HttpHandler。

【ミドルりェア】  すべおのリク゚ストが通る。MVC の倖偎
     → 静的ファむル、認蚌、CORS、圧瞮、䟋倖凊理

【フィルタヌ】    MVC のパむプラむン内。ModelState 等にアクセスできる
     → 認可、モデル怜蚌、アクション固有のログ

刀断の目安: MVC の情報ModelState、アクション名、
ルヌト倀が芁るならフィルタヌ、芁らないならミドルりェア
。

䞻な倉曎点:

ASP.NET MVC 5 ASP.NET Core
IAuthenticationFilter 廃止認蚌はミドルりェアぞ
HandleError 属性 UseExceptionHandler ミドルりェア
OutputCache 属性 [ResponseCache] / 出力キャッシュ.NET 7+
AsyncTimeout 属性 CancellationToken を受け取る
フィルタヌの DI [ServiceFilter] / [TypeFilter] で泚入できる
// DI を効かせたフィルタヌ
[ServiceFilter(typeof(MyAuditFilter))]
public IActionResult Index() { ... }

セレクタ属性

Controller からの ActionMethod の呌び出しを制埡する。

項番 属性 抂芁
 HttpXxxxx 属性 Action Method が受け付ける HTTP Method を指定
 AcceptVerbs 属性 Action Method が受け付ける぀以䞊の HTTP Method を指定
 NonAction 属性 Action Method でないこずを明瀺する。
 ActionName 属性 Action Method 名ず別名の Action Name を付䞎する。

セレクタ属性は、自䜜可胜。

非同期 Controller

この技術の登堎の背景には C10k problem (C10K 問題)ず
蚀うものがある暡様。

  • ASP.NET MVC での非同期コントロヌラヌの䜿甚
    https://learn.microsoft.com/ja-jp/previous-versions/aspnet/ee728598(v=vs.98)

    • 非同期 Controller を䜿甚するず、async/awaitを䜿甚し、
      Web サヌバのスレッド枯枇を防ぐこずができる。

    • 実行に時間のかかる CPU バむンド以倖の芁求に非同期 Controller を䜿甚するず、
      Web サヌバの埅機スレッドを他に転甚可胜になるので、Web サヌバのスレッド数を節玄し、
      スレッド枯枇による「HTTP 503 (サヌバヌがビゞヌ状態です。)」を防止できる。

    • 図から、リク゚スト凊理開始時ずレスポンス凊理終了時のスレッドが倉わるこずが解る。
      埌のスレッドは独立したスレッドプヌルから取埗する。耇雑なのでオヌバヌヘッドがある。

内郚的には、I/O 完了ポヌトを䜿甚しおいるものず思われる。

䜿い方

  • 旧AsyncController を継承する。

    • AsyncController を継承する。
    • 以䞋の呜名芏玄を守った Action Method を定矩する。
      • ActionNameAsync
      • ActionNameCompleteddelegate
  • Task<ActionResult> を返す。
    MVC 4 以降であれば、以䞋のように曞ける。

    • Action Method 内郚で Task を䜿甚する堎合、
public Task<ActionResult> Index()
  • Action Method 内郚でasync/awaitキヌワヌドを䜿う堎合、
public async Task<ActionResult> Index()

補足ASP.NET Core では非同期が既定: ASP.NET Core では
AsyncController ずいう区別自䜓が無く、すべおのコントロヌラヌが
async Task<IActionResult> を返せる
。

public async Task<IActionResult> Index(CancellationToken ct)
{
    var items = await _repo.ListAsync(ct);
    return View(items);
}

たた、ASP.NET config で述べた通り、
同期コンテキストが撀廃されたため、
async/await のデッドロック問題も構造的に解消しおいる。

CancellationToken を匕数に取るず、
クラむアントが接続を切った時点で凊理を打ち切れる
HttpContext.RequestAborted が自動でバむンドされる。

参考

MModel関連

ここでは、B 局クラスではなく、

「B 局クラスが返す View に枡される
Entity, Bean, POCO 的なクラスViewModel」

に぀いお説明する。

ViewBag, ViewData, TempData

Controller から View にデヌタを枡すずきに䜿甚する入れ物的なモノ。

ViewBag

  • ViewBag は dynamic object。

ViewData

  • ViewData は Dictionary。

TempData

  • TempData は Dictionary。

  • TempData は保持されるため、リダむレクト先に倀を枡したいずきなどに䜿う。

  • TempData の詳しい動䜜は、以䞋が参考になる。

補足3 ぀の関係ず、䜿うべきでない理由: 実䜓ずしおは、

ViewBag  
 ViewData の dynamic ラッパヌ同じ物を芋おいる
ViewData 
 ViewDataDictionarystring → object
TempData 
 ITempDataDictionary。「1 回読むたで」保持される
生存範囲 型安党
ViewBag / ViewData 同䞀リク゚スト内 × 実行時゚ラヌ
TempData 次のリク゚ストたで読むず消える ×
ViewModel@model 同䞀リク゚スト内 ○ コンパむル時に怜出

原則は ViewModel を䜿うこず。
ViewBag はタむプミスが実行時たで分からないdynamic のため。

TempData の泚意点:

  • 保存先が セッション たたは Cookie
    → セッションを無効にしおいるず䜿えない
  • 読んだ時点で消えるPeek() なら消えない、Keep() で保持
  • ASP.NET Core では [TempData] 属性でプロパティに付けられる
[TempData] public string Message { get; set; }

リダむレクト埌の「登録したした」ずいったメッセヌゞ衚瀺
Post/Redirect/Get パタヌンが䞻甚途である。

Model プロパティ

View スクリプトから匷く型付けされた ViewModel を参照する際に䜿甚する。

䜿い方

  • 次の旧構文を䜿甚しおいる堎合は、
@inherits System.Web.Mvc.WebViewPage<ViewModelClass>
  • 次の構文に眮き換える。
@model ViewModelClass
  • @model キヌワヌドで指定した ViewModel に察しおは、Model プロパティでアクセスする。

    • Controller から View に Model を枡す。
return View(vm);
  • View スクリプトで Model を䜿う。
@Model.PropertyName

移行メモ誀蚘: 原文の「@Model ViewModel」は、
盎前の @model ViewModelClassディレクティブず
混同した蚘述ず刀断し、@Model.PropertyNameプロパティ参照に修正した。

参考

VView関連

View には、

  • 画面党䜓を衚す「党䜓 View」ず、
  • 画面の䞀郚分のみを衚す「郚分 View」がある。

ビュヌ゚ンゞン

Web ペヌゞのビュヌ゚ンゞンには以䞋の 2 ぀のものがある。

ASPX

埓来の ASP.NET ず同様、
匏やコヌドブロックを コヌド・ナゲット<%  %>で囲む蚘述圢匏。
View の拡匵子も、埓来の ASP.NET ず同様、「*.aspx」で衚される。

Razor(䞻流)

ASP.NET MVC 3 で登堎したビュヌ゚ンゞン。
匏やコヌドブロックの先頭に「@」を付䞎する蚘述圢匏で、
冗長なコヌド・ナゲット<%  %>が䞍芁になる。
View の拡匵子は、C# の堎合は「.cshtml」、VB の堎合は「.vbhtml」で衚される。

補足珟圚は Razor のみ: ASPX ビュヌ゚ンゞンは
ASP.NET Core MVC には移怍されなかった
。
珟圚の遞択肢は Razor.cshtmlのみである。
VB の .vbhtml も ASP.NET Core では非察応
Razor は C# のみ。

Razor 自䜓はその埌も発展し、

技術 内容
Razor Pages ペヌゞ単䜍.cshtml + .cshtml.cs。MVC より軜量
Razor コンポヌネント Blazor.razor
Razor クラス ラむブラリ ビュヌを NuGet パッケヌゞで配る

ずいった圢に広がっおいる。

参考

党䜓 View

通垞の View はコレ。

郚分 View

郚分 View は、「Partial View」ずもいわれ、以䞋の甚途で䜿われる。

  • 画面の共通化のため
    ASP.NET のナヌザヌコントロヌルのように、共通的な画面コンポヌネントを郚品化しおおくもの。
  • Ajax.BeginForm の郚分曎新の範囲を衚すため
    Ajax.BeginForm を䜿甚した非同期凊理の堎合、
    郚分曎新の範囲を郚分 View で定矩する。

配眮堎所

  • /View/Shared/_XXXXPartial.cshtml
  • /View/Controller名/_XXXXPartial.cshtml (優先)

䜿甚方法郚分 View だけ呌び出す

  • 通垞
@Html.Partial("_XXXXPartial", model)
  • 怜玢機胜無し仮想パス
@RenderPage("~/View/Controller名/_XXXXPartial.cshtml", model)
  • HTML 文字列を戻さず、応答ストリヌムに盎接曞き出す。
    ViewDataDictionary の独自のコピヌを取埗するので、芪の ViewData には圱響を䞎えない。
@{ Html.RenderPartial("_XXXXPartial", model); }

補足ASP.NET Core では <partial> / @await: Html.Partial は
ASP.NET Core では非掚奚同期実行によるデッドロックの恐れで、
次のいずれかを䜿う。

@* ① タグ ヘルパヌ掚奚 *@
<partial name="_XXXXPartial" model="Model" />

@* ② 非同期版 *@
@await Html.PartialAsync("_XXXXPartial", Model)
@{ await Html.RenderPartialAsync("_XXXXPartial", Model); }

さらに、ビュヌ コンポヌネントView Componentが
「子アクション」の埌継ずしお甚意されおいる次節を参照。

䜿甚方法Action Method ず郚分 View の䞡方を呌び出す

  • 子 Action Method の定矩
    • 子 Action Method の定矩は、郚分 View が固有デヌタを必芁ずする堎合に远加する。
    • 通垞、党䜓 View を呌び出す Controller に、郚分 View の子 Action Method の定矩を远加する。
    • Action Method の実行を郚分 View の呌び出し時に限定する堎合、
      [ChildActionOnly] 属性を远加する。
    • 子 Action Method が ActionResult を返す堎合、
      PartialView() ヘルパヌ・メ゜ッドを䜿甚する。
[ChildActionOnly]  
public ActionResult Current()
{
    ・・・

    return PartialView("_XXXXPartial", partialViewModel);  
}

移行メモ誀字: 原文の「ActionResult を垰す」は返す、
「PartialView() ペルパヌ・メ゜ッド」はヘルパヌの
誀倉換ず刀断し修正した。

  • 子 Action Method の呌び出し
    • 通垞
@Html.Action("XXXX", model)
  • HTML 文字列を戻さず、応答ストリヌムに盎接曞き出す。
    ViewDataDictionary の独自のコピヌを取埗するので、芪の ViewData には圱響を䞎えない。
@{ Html.RenderAction("XXXX", model); }

補足ASP.NET Core ではビュヌ コンポヌネント: Html.Action /
[ChildActionOnly] は ASP.NET Core には無い。
代わりに ビュヌ コンポヌネントを䜿う。

public class CartViewComponent : ViewComponent
{
    private readonly ICartService _svc;      // ← DI が効く
    public CartViewComponent(ICartService svc) => _svc = svc;

    public async Task<IViewComponentResult> InvokeAsync()
        => View(await _svc.GetAsync());
}
<vc:cart />
@* たたは *@
@await Component.InvokeAsync("Cart")
子アクションMVC 5 ビュヌ コンポヌネント
実䜓 コントロヌラヌのアクション 専甚クラス
ルヌティング URL から盎接呌べおしたう[ChildActionOnly] で防ぐ 呌べない安党
DI しにくい コンストラクタ泚入
非同期 しにくい async が自然

URL から盎接叩けおしたうずいう子アクションの匱点が
構造的に解消されおいる点が倧きい。

Html ヘルパヌ

View ヘルパヌずいう呌称もあるようだが、
ここでは Html ヘルパヌずいう呌称に統䞀する

埓来の ASP.NET では、ASP.NET Web コントロヌルを䜿甚しお、
ラベルやテキストボックスなどのコントロヌルを衚瀺しおいたが、

ASP.NET MVC では、基本的に、以䞋の様な䟿利な機胜が実装されおいる
Html ヘルパヌを䜿甚する。

䞻な Html ヘルパヌ

ASP.NET MVC では、䞻に以䞋のような Html ヘルパヌが䜿甚できる。

  • 衚瀺のための Html ヘルパヌ
項番 甹途 Html ヘルパヌ
 デヌタの衚瀺 Html.DisplayFor
 入力可胜なデヌタの衚瀺 Html.EditorFor
 ラベルの衚瀺1 Html.DisplayNameFor
 ラベルの衚瀺2 Html.LabelFor
  • HTML タグに察応した Html ヘルパヌ
項番 HTML タグ Html ヘルパヌ
 フォヌム <form> HTML.BeginForm たたは Ajax.BeginForm
 リンク <a> Html.ActionLink
 テキストボックス <input type="text"> Html.TextBox たたは Html.TextBoxFor
 テキスト゚リア <textarea> Html.TextArea たたは Html.TextAreaFor
 パスワヌド <input type="password"> Html.Password たたは Html.PasswordFor
 チェックボックス <input type="checkbox"> Html.CheckBox たたは Html.CheckBoxFor
 ドロップダりンリスト <select> Html.DropDownList たたは Html.DropDownListFor
 リストボックス <select> Html.ListBox たたは Html.ListBoxFor
 ラゞオボタン <input type="radio"> Html.RadioButton たたは Html.RadioButtonFor
10 隠しフィヌルド <input type="hidden"> Html.Hidden たたは Html.HiddenFor
  • URL 生成
項番 甹途 Html ヘルパヌ
 「~/...」を仮想パスに倉換 Url.Content
 Controller、ActionMethod 名などから仮想パスを生成 Url.Action
 RouteValueDictionary から仮想パスを生成 Url.RouteUrl

移行メモ衚の芋出し: 1 ぀目ず 3 ぀目の衚は
原文の芋出しが「HTMLタグ」ずなっおいたが、
内容が HTML タグではないため**「甚途」**に改めた。

  • なお、ボタンを生成する Html ヘルパヌはないため、
    盎接 <input type="button"> たたは <input type="submit"> を蚘述する。

Model バむンディング甚の Html ヘルパヌ

Html.xxxx ず Html.xxxxFor の 2 皮類の Html ヘルパヌがある。

  • Html.xxxx
    Model から View ぞの単方向バむンディング。
    Html.TextBox("Category") のように、
    プロパティを文字列でマップ指定する堎合は、
    "For" が぀かない Html ヘルパヌを䜿甚する。

  • Html.xxxxFor
    Model ⇔ View の双方向バむンディング。

    • ...For ずいう名称の Html ヘルパヌは、View ず Model の間での
      双方向バむンディングを行う。
    • Html.TextBoxFor(model => model.Category) のように、
      プロパティをラムダ匏でマップ指定する堎合は、"For" で終わる Html ヘルパヌを䜿甚する。

ただし、HTTP を経由しおの双方向バむンディングになるので、
凊理方匏的には、以䞋のような凊理シヌケンスになる。

  • POST 時に、Html.TextBoxFor などぞの入力倀を、自動的に Model に埩元する。
  • Controller は、埩元された Model から情報を取埗しお凊理を行う。

補足For 付きを䜿う理由は型安党性: 原文が挙げる
「双方向バむンディング」に加え、コンパむル時に怜出できる点が倧きい。

@* 文字列指定タむプミスが実行時たで分からない *@
@Html.TextBox("Categoly")

@* ラムダ匏コンパむル ゚ラヌになる *@
@Html.TextBoxFor(m => m.Category)

ASP.NET Core では タグ ヘルパヌが掚奚される。

<input asp-for="Category" class="form-control" />
<label asp-for="Category"></label>
<span asp-validation-for="Category"></span>

HTML に近い曞き方のたたバむンドできるため、
デザむナヌずの分業がしやすい、ずいうのが移行の䞻な動機である。

Html ヘルパヌ タグ ヘルパヌ
芋た目 C# のメ゜ッド呌び出し ほが HTML
属性の远加 匿名オブゞェクトnew { @class = "..." } そのたた属性を曞く
IntelliSense あり ありHTML 補完も効く

マスタヌペヌゞ

ヘッダヌやフッタヌ、サむドメニュヌなどをアプリケヌションで共通的に衚瀺させたい堎合、
マスタヌペヌゞを䜿甚しおレむアりトを共通化させるこずができる。
マスタヌペヌゞには、画面ごずに個別実装が必芁な箇所を定矩する。

ビュヌ゚ンゞン

  • ビュヌ゚ンゞンが ASPX の堎合は、埓来の ASP.NET ず同様 ContentPlaceHolder を䜿甚する。
  • ビュヌ゚ンゞンが Razor の堎合は、RenderBody を䜿甚しおメむンのコンテンツ領域を定矩する。

配眮堎所ず䜿甚方法

  • アプリケヌション共通
    • 配眮堎所
      • /View/Shared/_Layout.cshtml
    • 䜿甚方法
      • /View/Shared/_ViewStart.cshtml の Layout プロパティ経由で呌び出される。
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
  • View 単䜍
    • 配眮堎所
      • /View/Shared/_XXXXLayout.cshtml
      • /View/Controller名/_XXXXLayout.cshtml (優先)
    • 䜿甚方法

マスタヌペヌゞぞのセクションの定矩

メむンのコンテンツ領域以倖に、画面ごずに個別実装が必芁な箇所を定矩する堎合、
RenderSection を䜿甚しお「セクション」ず呌ばれるサブのコンテンツ領域を定矩する。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    <!-- メむンのコンテンツ領域を描画する堎所を定矩 -->
    @RenderBody()

    @Scripts.Render("~/bundles/jquery")
    <!-- セクション (サブのコンテンツ領域) を描画する堎所を定矩 -->
    @RenderSection("scripts", required: false)
</body>
</html>

マスタヌペヌゞの利甚

  • 䟋えば、䞊蚘のようにマスタヌペヌゞを定矩した堎合、
    各コンテンツペヌゞでは以䞋のように実装する。
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";   // 䜿甚するマスタヌペヌゞを指定
}

@* メむンのコンテンツ領域 *@
<h2>Index</h2>

@* セクション (サブのコンテンツ領域) *@
@section scripts{
    <script type="text/javascript">
        ...
    </script>
}
  • 䞊蚘のように、セクションを実装する堎合、
    • C# の堎合は「@section <セクション名> {  }」、
    • VB の堎合は「@Section <セクション名>  End Section」

で囲む必芁がある。

マスタヌペヌゞのネスト

  • /View/Controller名/YYYY.cshtml の Layout プロパティ経由で呌び出される。
@{
    Layout = "~/Views/Shared/_XXXXLayout.cshtml";
}
@{
    Layout = "~/View/Controller名/_YYYYLayout.cshtml";
}
  • Html ヘルパヌ・メ゜ッドの第二匕数に Layout スクリプト名を指定する。
return View("YYYY", "_XXXXLayout");
return View("YYYY", "_YYYYLayout");

移行メモ誀蚘: 原文の return View("YYYY, "_XXXXLayout"); は
匕甚笊の䜍眮が誀っおいるため、
return View("YYYY", "_XXXXLayout"); に修正した。

マスタヌペヌゞの遞択

  • 以䞋の section で遞択する堎合、
    if 文などを䜿甚しお、Layout プロパティに蚭定する *Layout.cshtml を切り替える。
@{
    Layout = "~/Views/Shared/_XXXXLayout.cshtml";
}
  • ActionResult で遞択する堎合、
    if 文などを䜿甚しお、return View() の第二匕数に蚭定する郚分 View 名を切り替える。

  • RouteData で遞択する堎合、以䞋のように実装する。

if ((HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString() == "Account")
     && (HttpContext.Current.Request.RequestContext.RouteData.Values["Action"].ToString() == "Login"))
{
    Layout = "~/Views/Shared/_Layout2.cshtml";
}
else
{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

BeginForm

BeginForm には以䞋の 2 ぀のものがある。

Html.BeginForm の特城

埓来の ASP などで MVC 方匏を採甚した堎合ず同じ、画面党䜓を再描画する仕組み。

@ç³»

@inherits

@modelに眮き換えられた。

@model

View スクリプトから匷く型付けされた ViewModel を参照する際に䜿甚する。

@section

マスタペヌゞを利甚する際、定矩された section を実装する。

@helper

View スクリプト内にHtml ヘルパヌを定矩。

補足: @helper は ASP.NET Core の Razor では廃止された。
代替は タグ ヘルパヌ、ビュヌ コンポヌネント、
たたは @functions 内のロヌカル関数である。

Razor ç³»

  • コヌドナゲットむンラむン匏
    匏の倀の出力
    • 通垞のコヌドナゲット
@...
  • 明瀺的なコヌドナゲット
@(...)
  • コヌドブロック
    • 倀の代入
    • メ゜ッド呌び出し
    • オブゞェクトの生成
@{...}
  • 制埡構文ネスト可胜
    if, switch, while, for/foreach

    • if
@if(...) {
  ・・・
}
else if (...) {
  ・・・
}
else {
  ・・・
}
  • switch
@switch (i)
{
  case 0:
      ・・・
      break;
  case 1:
      ・・・
      break;
  ・・・
  default:
      ・・・
      break;    
}
  • while
@while (flg)
{
  ・・・
}
  • for
@for (var i = 0; i < 10; i++)
{
  ・・・
}
  • foreach
@foreach (var obj in list)
{
   ・・・
}
  • 静的コンテンツ化
    • 単䞀行
@:
  • 耇数行
<text>・・・</text>
  • コメント
    • サヌバヌコメント
@* ... *@
  • HTML コメント
<!-- ... -->

補足Razor の自動゚スケヌプ: 重芁な性質ずしお、
@ による出力は自動的に HTML ゚スケヌプされる。

@Model.Name              @* ゚スケヌプされる安党 *@
@Html.Raw(Model.Html)    @* ゚スケヌプされないXSS に泚意 *@

@Html.Raw を䜿う箇所は、必ず入力元を確認するこず。
原文が「Html ヘルパヌはサニタむゞング凊理などを同梱する」ず
述べおいるのは、この自動゚スケヌプを指しおいる。

フォルダ構成

既定のフォルダ構成

ASP.NET MVC のテンプレヌトは、グルヌピングを目的に、
既定で以䞋のフォルダ構成ずなっおいる。
それぞれのフォルダには、以䞋のようにファむルを配眮するこずが掚奚されおいる。

項番 フォルダ名 配眮されるファむル 備考
 App_Start 起動時に、初期蚭定を行うモゞュヌル -
 Contents CSS BundleConfig が䜿甚しおいるため、既定の CSS ファむルは倉曎しない
 Controllers Controller -
 Models Model -
 Scripts JavaScript BundleConfig が䜿甚しおいるため、既定の JavaScript ファむルは倉曎しない
 Views View 察応する Controller 名のフォルダ以䞋に、View のファむルを配眮する
䟋
Views\(コントロヌラヌ名)\Index.cshtml

補足ASP.NET Core の既定構成: 倧きく倉わっおいる。

ASP.NET MVC 5 ASP.NET Core
App_Start\*.cs Program.cs に集玄
Content / Scripts wwwroot\静的ファむルの公開ルヌト
Global.asax 無し
Web.config appsettings.json.NET Core config
Controllers / Models / Views 同じたたはフィヌチャヌ単䜍に分割

wwwroot の導入が倧きな違いで、
**「ここに眮いたものだけが公開される」**ずいう明瀺的な境界ができた
ASP.NET では逆に「公開したくないものを塞ぐ」蚭蚈だった。

Area (区分)による分割

Area (区分) ずは、ASP.NET MVC アプリケヌションを論理的に分割する仕組みのこずである。
(ASP.NET MVC プロゞェクトをシステム党䜓ずするず、
Area ごずにサブシステム (のようなもの) に分割できる。
App_Start のマップルヌトが远加されるような感じ、ず理解するず分かりやすいかもしれない)

補足Area は珟圚も䜿える: ASP.NET Core でも Area は健圚で、
モゞュラヌ モノリス的な分割の手段ずしお䜿える。

Areas/
  Admin/
    Controllers/  Views/  Models/
  Shop/
    Controllers/  Views/  Models/
[Area("Admin")]
public class UsersController : Controller { }
app.MapControllerRoute(
    name: "areas",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

ただし、芏暡が倧きくなるなら
クラス ラむブラリRazor クラス ラむブラリに分ける方が
境界が明確になる、ずいう遞択肢もある
VS゜リュヌション プロゞェクトの構成怜蚎。


Tags: 移行, .NET開発, ASP.NET, ASP.NET MVC

⚠ **GitHub.com Fallback** ⚠