ASP.NET Core
ナビゲーションに移動
検索に移動
| .NET Core | C Sharp | ASP.NET | Razor | Docker | .NET Core Console
目次
ASP.NET Core
- 本書からのメモ
- ASP.NET Coreドキュメント]
Download
This product collects usage data
- More information and opt-out https://aka.ms/dotnet-cli-telemetry
- 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
インストール
Mac
- https://docs.microsoft.com/ja-jp/aspnet/core/getting-started/?view=aspnetcore-5.0&tabs=macos
- https://dotnet.microsoft.com/download/dotnet/5.0
- https://docs.microsoft.com/ja-jp/dotnet/core/install/macos
SDK
- Visual Studio Code をダウンロードしてインストールします。
- .NET SDK をダウンロードしてインストールします。
- Visual Studio Code マーケットプレースから C# 拡張機能をインストールします。
アンインストール1
- 例
sudo rm -rf /usr/local/share/dotnet/sdk/6.0.200
Ubuntu
削除する場合
- SDK
$ cd /usr/local/share $ ls dotnet $ sudo rm -rf dotnet
- .NET ランタイム
sudo rm -rf /usr/local/share/dotnet/shared/Microsoft.NETCore.App/$version
プロジェクト作成
$ dotnet new webapp -o aspnetcoreapp
- 開発証明書を信頼
$ dotnet dev-certs https --trust
- アプリの実行
$ cd aspnetcoreapp $ dotnet watch run
- https://localhost:5001/ にアクセス
サブフレームワーク
サブフレームワーク | 内容 |
---|---|
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アプリケーションテンプレート
dotnet new
- .NET Core
- 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
- ActionResult<T>
IActionResult
結果 | ヘルパーメソッド | 概要 |
---|---|---|
ViewResult | View() | テンプレートに基づいてページを出力 |
ContentResult | Content() | 指定されたテキストを出力 |
RedirectResult | Redirect() | 指定されたパスに移動 |
RedirectToActionResult | RedirectToAction() | 指定されたアクションに移動 |
FileContentResult | File() | 指定されたバイト配列をファイルとして出力 |
NotFoundResult | NotFound() | 404(Not Found)エラーを出力 |
実行
http://localhost:58697/Hello/Index
ルーティング
- プロジェクト直下のStartup.cs(Configureメソッド)で定義
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { : app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
template
記号 | 意味 |
---|---|
? | パラメータが省略可能であることを意味する |
= | パラメータのデフォルト値 |
ビュー
- 出力にかかわる部分はRazorテンプレート(ビュー)にゆだねるべき
Razor
コントローラーの修正
// Controllerクラスを継承 public class HelloController : Controller { // アクションメソッド // publicメソッドでクライアントからのリクエストを処理 public IActionResult Greet() { // ビュー変数を準備 // ViewBag.変数名 = 値(任意のオブジェクト) // ViewData["変数名"] = 値(任意のオブジェクト) ViewBag.Message = "Hello ASP.NET Core workd."; // テンプレートの呼び出し // 引数なしで呼び出した場合、/Views/コントローラー名/アクション名.cshtml が対応する // テンプレート名は変更可能 View("Hoge"); return View(); } }
ビューの追加
- コントローラー、アクションメソッドのコンテキストメニューから
{{ref_image dnet_add_view.jpg}}
@{ ViewData["Title"] = "Greet"; } <h2>Greet</h2> <p>@ViewBag.Message</p>
Razor構文
構文 | 意味 |
---|---|
@... | テンプレートを埋め込む。コードナゲットと呼ばれる |
@{...} | 複数行の分を表す。結果を出力しない |
- テンプレートに記述していないヘッダー・フッター
- /Views/Shared/_Layout.cshtml で定義されている
- @RenderBody() にて出力が生成
モデル
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オブジェクトエクスプローラーで確認
データアクセス
コントローラーにアクションメソッドを追加
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ディレクティブで型を宣言することで型キャストなどの手間を省ける
実行
スキャフォールディング
- コードの大枠を自動生成する機能
Entity Frameworkを使用したビューがあるMVCコントローラー
- Controllersフォルダのコンテキストメニュー - 追加 - コントローラー - Entity Frameworkを使用したビューがあるMVCコントローラー
- CRUD機能を備えたコントローラーが作成される
- 実行
テンプレート
データ型に応じ出力を変化
プロパティをそのまま表示
@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>
表示名が表示される
ハイパーリンクを生成
- Editアクションに対して、idパラメータとして@item.Id を渡すリンクを作成させる
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a>
- 以下のようなHTMLが生成される
<a href="/Books/Edit/1">Edit</a>
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バンドルでの相対パスを使用
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>
Web API
Docker LInuxイメージを Mac で実行
ローカルで実行
$ git clone https://github.com/dotnet/dotnet-docker $ cd dotnet-docker/samples/aspnetapp/aspnetapp $ dotnet run
Dockerで実行
- Docker Desktopをインストール
- Visual Studio Code にDocker拡張機能をインストール
$ cd dotnet-docker/samples/aspnetapp
- aspnetapp という名前をつけ、Dockerfile を探し(末尾にピリオド)実行
- 完了したらイメージを確認
$ docker build -t aspnetapp . : $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE aspnetapp latest fedab8c51899 4 minutes ago 210MB
- 実行
docker run -it --rm -p 5000:80 --name aspnetcore_sample aspnetapp
環境の切り替え
環境変数 DOTNET_ENVIRONMENT、ASPNETCORE_ENVIRONMENT(優先)
- Development : 開発者例外ページが有効
- Staging
- Production : DOTNET_ENVIRONMENT と ASPNETCORE_ENVIRONMENT が設定されていない場合既定値
- ASPNETCORE_ENVIRONMENT を使用してアプリを起動するときに現在のセッションに ASPNETCORE_ENVIRONMENT を設定するには、コマンド プロンプトまたは PowerShell で次のコマンドを使用する
$Env:ASPNETCORE_ENVIRONMENT = "Staging" dotnet run --no-launch-profile
- ASP.NET Core 6.0
var builder = WebApplication.CreateBuilder(new WebApplicationOptions { ApplicationName = typeof(Program).Assembly.FullName, ContentRootPath = Directory.GetCurrentDirectory(), EnvironmentName = Environments.Staging, WebRootPath = "customwwwroot" }); Console.WriteLine($"Application Name: {builder.Environment.ApplicationName}"); Console.WriteLine($"Environment Name: {builder.Environment.EnvironmentName}"); Console.WriteLine($"ContentRoot Path: {builder.Environment.ContentRootPath}"); Console.WriteLine($"WebRootPath: {builder.Environment.WebRootPath}"); var app = builder.Build();
Tips
error NU1101: パッケージ Microsoft.AspNetCore.SpaProxy が見つかりません
- nuget のソースを再構築する
C:\workspaces\aspdotnetangular\aspdotnetangular.csproj : error NU1101: パッケージ Microsoft.AspNetCore.SpaProxy が見つかりません。ソース Microsoft Visual Studio Offline Packages には、この ID のパッケージが存在しません。 [C:\workspaces\aspdotnetangular\aspdotnetangular.sln]
> dotnet nuget list source 1. Microsoft Visual Studio Offline Packages [有効] C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\
> dotnet new nugetconfig --force
> dotnet nuget list source 登録されているソース: 1. nuget [有効] https://api.nuget.org/v3/index.json
サーバー証明書の検証をスキップ
- https://qiita.com/TsuyoshiUshio@github/items/f238a2a2c1483c287e4b
System.Net.Http.HttpRequestException: The SSL connection could not be established
var httpClientHandler = new HttpClientHandler(); httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPlicyErrors) => true; var httpClient = new HttpClient(httpClientHandler);
© 2006 矢木浩人