15,489 バイト追加
、 2020年2月15日 (土) 07:30
==ASP.NET Core==
[C#][ASP.NET][Razor]
{{amazon|B078CXYZ6L}}
*本書からのメモ
====Download====
*https://www.microsoft.com/net/learn/get-started/windows
=====This product collects usage data=====
*More information and opt-out https://aka.ms/dotnet-cli-telemetry
Resources
*Core Documentation https://aka.ms/dotnet-docs
*SDK Documentation https://aka.ms/dotnet-cli-docs
*Release Notes https://aka.ms/20-p2-rel-notes
*Tutorials https://aka.ms/dotnet-tutorials
===サブフレームワーク===
{|class="wikitable"
!サブフレームワーク
!内容
|-
|ASP.NET MVC
|MVCモデルに基づいて設計されたフレームワーク
|-
|ASP.NET Web API
|Web経由で利用できるAPIを実装するための仕組み
|-
|Razor Pages
|MVVMパターンフレームワーク、画面中心の場合ASP.NET MVCよりもシンプルに開発可 https://codezine.jp/article/corner/718
|-
|SignalR
|リアルタイム通信を実装するためのライブラリ、アプリ側で低レベル手続きを意識しなくてもよい
|-
|}
====ASP.NET Web API====
*ASP.NET Web API のランタイム環境は、ASP.NET MVC以外のアプリケーションから利用できるように、ASP.NET MVCランタイム環境から完全に切り離されている。
*以下の点がMVCよりも優れている
**コードと結果のシリアル化の切り離し:メソッドデータを返すだけ、メソッド内で結果をシリアル化しない
**コンテンツネゴシエーション:リクエスト元のデバイスに返されるデータのシリアル化は、フォーマッターによって処理される。送信クエリのAcceptヘッダーに基づき自動
**IIS以外でのホスティング:IIS不要、Windowsサービスやコンソールアプリケーション等でもホスティング可能
==基本==
===ASP.NET Core Webアプリケーションテンプレート===
[[File:0252_dnetcore_template.jpg]]
====dotnet new====
*Visual Studio Code
*https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-new?tabs=netcore21
$ dotnet new mvc
==MVC==
===コントローラー===
====追加====
*/Controllers コンテキストメニュー、追加 - コントローラー
*クラス名は、「Controler」で終わらなければならない
using Microsoft.AspNetCore.Mvc;
namespace QuickMaster.Controllers
{
// Controllerクラスを継承
public class HelloController : Controller
{
// アクションメソッド
// publicメソッドでクライアントからのリクエストを処理
public IActionResult Index()
{
// アクションメソッドの戻り値は、IActionResult
IActionResult result = Content("Hello ASP.NET Core workd.");
return result;
}
}
}
====IActionResult====
{|class="wikitable"
!結果
!ヘルパーメソッド
!概要
|-
|ViewResult
|View()
|テンプレートに基づいてページを出力
|-
|ContentResult
|Content()
|指定されたテキストを出力
|-
|RedirectResult
|Redirect()
|指定されたパスに移動
|-
|RedirectToActionResult
|RedirectToAction()
|指定されたアクションに移動
|-
|FileContentResult
|File()
|指定されたバイト配列をファイルとして出力
|-
|NotFoundResult
|NotFound()
|404(Not Found)エラーを出力
|-
|}
====実行====
http://localhost:58697/Hello/Index
[[File:0245_dnet_core_controller.jpg]]
===ルーティング===
*プロジェクト直下のStartup.cs(Configureメソッド)で定義
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
*UseMvcは、ASP.NET MVCを有効にする
*UseMvcには、ルーティング設定をする、IRouteBuilderが渡されるので、新たなルートを追加できる
=====template=====
{|class="wikitable"
!記号
!意味
|-
|?
|パラメータが省略可能であることを意味する
|-
|=
|パラメータのデフォルト値
|-
|}
===ビュー===
*出力にかかわる部分はRazorテンプレート(ビュー)にゆだねるべき
====Razor====
*HTMLにC#などのコードを埋め込むためのテンプレートエンジン
**HTMLをベース
**タグヘルパー
**C#構文を利用できる
*再利用の仕組み
*[https://docs.microsoft.com/ja-jp/aspnet/core/mvc/views/razor?view=aspnetcore-2.1 構文リファレンス]
====コントローラーの修正====
// Controllerクラスを継承
public class HelloController : Controller
{
// アクションメソッド
// publicメソッドでクライアントからのリクエストを処理
public IActionResult Greet()
{
// ビュー変数を準備
// ViewBag.変数名 = 値(任意のオブジェクト)
// ViewData["変数名"] = 値(任意のオブジェクト)
ViewBag.Message = "Hello ASP.NET Core workd.";
// テンプレートの呼び出し
// 引数なしで呼び出した場合、/Views/コントローラー名/アクション名.cshtml が対応する
// テンプレート名は変更可能 View("Hoge");
return View();
}
}
====ビューの追加====
*コントローラー、アクションメソッドのコンテキストメニューから
[[File:0244_dnet_add_view.jpg]]
@{
ViewData["Title"] = "Greet";
}
<h2>Greet</h2>
<p>@ViewBag.Message</p>
=====Razor構文=====
{|class="wikitable"
!構文
!意味
|-
|@...
|テンプレートを埋め込む。コードナゲットと呼ばれる
|-
|@{...}
|複数行の分を表す。結果を出力しない
|-
|}
[[File:0247_dnet_razor.jpg]]
*テンプレートに記述していないヘッダー・フッター
**/Views/Shared/_Layout.cshtml で定義されている
**@RenderBody() にて出力が生成
===モデル===
*データベース、外部サービスへのアクセスはじめ、ビジネスロジックを担う
*ASP.NET MVCでは、モデルに相当する機能はなく、モデルとして何を利用するかは開発者の自由
====Entity Framework====
*O/Rマッパーの一種
*データベース連携には欠かせない存在
====モデルクラス====
*POCO(Plain Old Clr Object)
*ルール
**クラス名はテーブル名と同名
**プロパティは、列と同名
**主キーはId
====コンテキストクラス====
*単なるPOCOであるモデルクラスをデータベースに橋渡しする
*Entity Frameworkを使った操作はすべてコンテキストクラスを基点に行う
using Microsoft.EntityFrameworkCore;
namespace QuickMaster.Models
{
// DbContextを継承
public class MyContext : DbContext
{
// コンストラクタ
public MyContext(DbContextOptions<MyContext> options) : base(options)
{
}
// モデルクラスへのアクセッサ
public DbSet<Book> Book { get; set; }
}
}
=====コンテキストである条件=====
*DbContextを継承
*DbContextOptions<TContext>を受け取るコンストラクタを持つ
*DbSet<TModel>型のpublicプロパティを持つ
=====appsettings.json=====
*プロジェクトは以下のappsettings.jsonで接続情報を定義
{
:
"ConnectionStrings": {
"MyContext": "Server=(localdb)\\mssqllocaldb;Database=QuickMaster;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
*アプリケーションにコンテキストクラスを登録
=====Startups.cs=====
public class Startup
{
:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// コンテキストクラスを登録
services.AddDbContext<MyContext>(
options => options.UseSqlServer(Configuration.GetConnectionString("MyContext")));
}
}
=====マイグレーション=====
*NuGetパッケージマネージャーコンソール
PM> Install-Package Microsoft.EntityFrameworkCore.Tools
PM> Add-Migration Initial
PM> Update-Database
*SQLServerオブジェクトエクスプローラーで確認
[[File:0251_dnet_sqlsrv.jpg]]
===データアクセス===
====コントローラーにアクションメソッドを追加====
public class HelloController : Controller
{
private readonly MyContext _context;
// DI(依存性注入)
public HelloController(MyContext context)
{
this._context = context;
}
public IActionResult List()
{
// コンテキストからプロパティにアクセスするとすべてのレコードを取得できる
// Viewメソッドに渡すことで、テンプレートに引き渡すことができる
return View(this._context.Book);
}
:
}
====テンプレートの追加====
[Razor]
*上記手順でビューを追加
@model IEnumerable<QuickMaster.Models.Book>
@{
ViewData["Title"] = "List";
}
<h2>List</h2>
<table class="table">
<thead><tr><th>Title</th><th>Price</th><th>Publisher</th><th>Sample</th></tr></thead>
<tbody>
@* Bookを出力 *@
@foreach (var item in Model)
{
<tr>
<td>@item.Title</td>
<td>@item.Price</td>
<td>@item.Publisher</td>
<td>@item.Sample</td>
</tr>
}
</tbody>
</table>
*View()にモデルを渡した場合、@modelディレクティブで型を宣言することで型キャストなどの手間を省ける
====実行====
[[File:0246_dnet_model_list.jpg]]
===スキャフォールディング===
*コードの大枠を自動生成する機能
====Entity Frameworkを使用したビューがあるMVCコントローラー====
*Controllersフォルダのコンテキストメニュー - 追加 - コントローラー - Entity Frameworkを使用したビューがあるMVCコントローラー
*CRUD機能を備えたコントローラーが作成される
[[File:0248_dnet_sf.jpg]]
*実行
[[File:0250_dnet_sf_index.jpg]]
[[File:0249_dnet_sf_edit.jpg]]
===テンプレート===
====データ型に応じ出力を変化====
=====プロパティをそのまま表示=====
@model.Title
=====model => model.プロパティ名とすることでデータ型に応じて適切な形式で出力=====
**bool型ではチェックボックス
**EmailAddress/Url型ではハイパーリンク
@Html.DisplayNameFor(model => model.Title)
=====モデルアトリビュート=====
*モデルに表示名を定義
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
namespace QuickMaster.Models
{
public class Book
{
public int Id { get; set; }
[DisplayName("書名")]
public string Title { get; set; }
[DisplayName("価格")]
public int Price { get; set; }
[DisplayName("出版社")]
public string Publisher { get; set; }
[DisplayName("サンプル")]
public bool Sample { get; set; }
}
}
=====テンプレート=====
*プロパティの表示名を出力
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Publisher)
</th>
<th>
@Html.DisplayNameFor(model => model.Sample)
</th>
</tr>
</thead>
=====表示名が表示される=====
[[File:0243_display_name.jpg]]
=====ハイパーリンクを生成=====
*Editアクションに対して、idパラメータとして@item.Id を渡すリンクを作成させる
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a>
*以下のようなHTMLが生成される
<a href="/Books/Edit/1">Edit</a>
===Htmlヘルパー===
*https://tokkan.net/csharp/asp3.html
====一覧====
*Html.ActionLink()
*Html.BeginForm()
*Html.CheckBox()
*Html.DropDownList()
*Html.EndForm()
*Html.Hidden()
*Html.ListBox()
*Html.Password()
*Html.RadioButton()
*Html.TextArea()
*Html.TextBox()
====Html.ActionLink====
====Html.DropDownList====
*https://docs.microsoft.com/ja-jp/aspnet/mvc/overview/older-versions/working-with-the-dropdownlist-box-and-jquery/using-the-dropdownlist-helper-with-aspnet-mvc
====Html.TextArea====
*TextArea
*TextAreaFor
@Html.TextAreaFor(model=>model.SomeMulitiLineText, new {@style="max-width:100%; width:80%", rows=34})
===アクション===
====モデルバインド====
*アクションメソッドでは、リクエストデータと同名の引数を用意しておくことで、対応する値を自動的に引き渡すことができる
*デフォルトで定義されたルートでは、{controller}/{action}/{id} のように定義されていて、Books/Details/13 の場合、id=13 がセットされる
*ルートパラメータだけでなく、クエリパラメータにも対応 /Books/Details?id=13 でも同様にアクセス可能
// GET: Books/Details/5
public async Task<IActionResult> Details(int? id)
{ ... }
====フォームの生成====
*<form>にasp-action属性を付与することで、指定したアクションをポスト先とするフォームを生成できる
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Id" />
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
:
</form>
*以下のようなHTMLに展開される
<form action="/Books/Edit/1" method="post">
<input type="hidden" data-val="true" data-val-required="The Id field is required." id="Id" name="Id" value="1" />
<div class="form-group">
<label class="control-label" for="Title">書名</label>
<input class="form-control" type="text" id="Title" name="Title" value="TITLE-AA" />
<span class="text-danger field-validation-valid" data-valmsg-for="Title" data-valmsg-replace="true"></span>
</div>
:
</form>
====アクションの処理====
==バンドル==
===ASP.NETバンドルでの相対パスを使用===
*ASP.NETバンドルでの相対パスを使用
==WebConfig の変換==
*https://docs.microsoft.com/ja-jp/previous-versions/dd465326(v=vs.110)?redirectedfrom=MSDN
*変換ファイルのルート要素の開始タグで、XML-Document-Transform 名前空間を指定する
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
*以下の例では、"SetAttributes" 変換により、値が "MyDB" の属性 "name" を "Match" ロケーターが検出した場合にのみ "connectionString" の値に"ReleaseSQLServer" を使用するよう変更されます
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
*以下の例では、"Replace" 変換により Web.config ファイルの <customErrors> セクション全体が置換されます。
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>