SlideShare a Scribd company logo
1 of 83
Download to read offline
C#, .NET 6, Blazor WebAssembly,
ASP.NET Web API, Azure による
アプリ開発 – その2
鈴⽊ 章太郎
Elastic テクニカルプロダクトマーケティングマネージャー/エバンジェリスト
デジタル庁 省庁業務グループ ソリューションアーキテクト
Elastic
Technical Product Marketing
Manager/Evangelist
デジタル庁
省庁業務グループ
ソリューションアーキテクト
元 Microsoft Technical Evangelist
Twitter : @shosuz
Shotaro Suzuki
l 前回までの復習
l Blazor 概要
l 今回作成する Web アプリケーションの概要
l Blazor WebAssembly プロジェクト作成
l Web API コントローラー追加、モデル追加
l Entity Framework による Code First データベース作成
l 商品サービス、商品リスト、カテゴリーサービス等必要なサービス、
CRUD 処理等の実装
l 検索サービスの追加と検索コンポーネントの実装
l カートサービス、認証・ユーザー登録
l その他の機能の実装と UI/UX の変更
アジェンダ
リソースと今後の展望
l セッションでご紹介した EC アプリ .NET 5版ですが、参考にさせて戴きました。
l https://github.com/patrickgod/BlazorEcommercePreviewYT
l 3⽉は、EF 連携-DB ⽣成、各サービス実装、検索機能 (Elastic による強化)等
l 将来的に microservices 化などできるといいなと思っています(4⽉︖W)
l 今回、共演した宝達さんがデモされた OpenShift へのデプロイ、さらに進めて、ARO
(Azure Red Hat OpenShift)にデプロイも⾯⽩いかなと思っています。
l 次回もよろしくお願いします︕
検索機能の実装の前までご説明し、カートサービス、認証、ユーザー登
録、等はもし可能であれば、次回に回させて戴きたく…
UI/UX はどこの箇所にも含まれていますが、ページネーション等は別途
取り上げて次回⼊れます。
Blazor 概要
Modern Web UI with .NET & Blazor
Server WebAssembly Hybrid
HTML、CSS、.NET、C#... JavaScript の代わりに Open Web 標準でアプリ開発
どこにでもホストできる
MVC
Razor
Pages
Blazor
HTTP
APIs
SignalR
Part of the ASP.NET Core family
Web UI Services
Worker gRPC
SPA
Blazor – .NET 5 まで
Blazor Server Blazor WebAssembly
DOM
Blazor
WebAssembly
.NET
Razor Components
Blazor
.NET
Razor Components
DOM
SignalR
ü DB アクセス含むサーバー機能へのフルアクセス
ü ⾼速なスタートアップ
ü コードがサーバーから離れない
ü 古いブラウザとシンクライアントをサポート
ü 永続的な接続が必要
ü UI の遅延が⾼い
ü完全にクライアント側で実⾏
ü必要なサーバー コンポーネントなし
ü静的サイトとしてホスト
üオフラインで実⾏可能
ü⼤きなダウンロードサイズ
üランタイムパフォーマンスの低下
Blazor Server (.NET 5) Blazor WebAssembly (.NET 5)
Blazor – .NET 6 による強化
Blazor Server Blazor WebAssembly
DOM
Blazor
WebAssembly
.NET
Razor Components
Blazor
.NET
Razor Components
DOM
SignalR
Blazor WebAssembly の事前 (AOT) コンパイル対応
Blazor WebAssembly アプリのダウンロードサイズの縮⼩
Error Boundaries
Razor コンポーネント型の推論とジェネリック型の制約
動的コンポーネント
プリレンダリング中の Blazor コンポーネント状態の永続性
Hot Reload, Native File Reference, 他多数
.NET 6
Blazor Server と Blazor WebAssembly の
開発モデルの違い
Blazor Server Blazor WebAssembly
DOM
Blazor
WebAssembly
.NET
Razor Components
Blazor
.NET
Razor Components
DOM
SignalR
Blazor Server
• 開発モデルは C/S 型に近い
• DOM(ブラウザ UI)と Blazor ランタイム(仮想 DOM)
がやりとりし UI 描画(差分更新)
• 画⾯の⼊出⼒部分のみをリモートデスクトップのようにブラウザ
側に持ってきているとみなせる
• SignalR(Web ソケット通信)
• DB に直接アクセス可能
• Web アプリケーションを Client - Server 型に近いモデルで
開発可能
• Web サーバとの常時接続が必要
• サーバ側でリソース効率の⾼いアプリの作り⽅が必要
• Hot Reload
Blazor WebAssembly
• サンドボックス制限
• DB アクセス不可 → Native File Reference による
ローカル DBアクセス
• Web API を介して DB アクセス
• 静的な Web サーバにホスト
• アプリ全体がダウンロード(⼤きくなりがち)
• DOM(ブラウザ UI)と Blazor ランタイム(仮想
DOM)がやりとりしUI 描画(差分更新)、ランタイム
が Blazor アプリ(UI ロジック)とやりとりする
• Hot Reload (デバッグなしで実⾏)
Web Assembly(WASM) とは
• Web ブラウザ上でバイナリコードを直接実⾏できる
• 2019 年 12 ⽉ W3C 勧告、正式なウェブ標準に認定
• 様々な⾔語のバイナリコードを主要なブラウザのサンドボックス内で動作可能
• Web Assembly バイナリコードへのコンパイラなどのツールセットが必要
Edge
Chrome
Safari
Firefox
Web Assembly
バイナリコード
(W3C 標準技術)
C++ WASM
コンパイラ
Rust WASM
コンパイラ
C WASM
コンパイラ
SQLite ソースコード(C)
Rust ソースコード
C++ ソースコード
.NET 6 における
Blazor WebAssembly 新機能
• 事前 (AOT) 実⾏コンパイル
• カスタム要素
• ⼩規模なアプリサイズ
• Native File Reference
• Hot Reload
• Component, .NET, HTML, CSS…
…その他数⼗個の更新あり
Blazor WebAssembly ⼩規模なアプリサイズ
.NET 5
• Publish size: 1.7 MB
.NET 6
• Publish size: 1.0 MB
• ~40% size reduction
Blazor WebAssembly のホスティング
ASP.NET
Blazor
WebAssem
bly
APIs
Globally
distributed
hosting
Blazor
WebAssem
bly
Serverless
functions
APIs
App Services Azure Static Web Apps
ASP.NET
Globally
distributed
hosting Microservices
Blazor
WebAssembly
APIs
Blazor
WebAssembly
APIs
Get started with Blazor
• Go to https://blazor.net
• Install the .NET SDK
• .NET Conf 2021 https://www.dotnetconf.net/
• .NET Conf 2021 – videos/slides/demos
https://github.com/dotnet-presentations/dotNETConf/tree/master/2021/MainEvent/Technical
Visual Studio Visual Studio for Mac Visual Studio Code
+ C# extension
今回作成する Web アプリケーションの概要
ASP.NET Core Blazor プロジェクトの構造
https://docs.microsoft.com/ja-jp/aspnet/core/blazor/project-structure?view=aspnetcore-6.0
Blazor WebAssembly アプリの初期ファイルとディレクトリ構造
[Client]
• Connected Service
• Dependencies
• Pages
• Properties
• Shared
• wwwrooot
• _imports.razor
• App.razor
• Program.cs
[Server]
• Connected Service
• Dependencies
• Controllers
• Pages
• Properties
• appsettings.json
• Program.cs
[Shared]
• Connected Service
• Dependencies
• WeatherForecast.cs
ASP.NET Core Blazor のホスティング モデル
https://docs.microsoft.com/ja-jp/aspnet/core/blazor/hosting-models?view=aspnetcore-6.0
• Blazor WebAssembly hosting model を使⽤すると、次のようになります。
• Blazor アプリ、その依存関係、.NET ランタイムが並⾏してブラウザーにダウンロードされます。
• アプリがブラウザー UI スレッド上で直接実⾏されます。
• 次の展開戦略がサポートされています。
• ASP.NET Core でのホストされた展開
• Blazor アプリは、ASP.NET Core アプリによって提供されます。
• "ホストされたデプロイ" により、 WebAssembly アプリが、Web サーバー上で実⾏されている ASP.NET Core アプリからブラウザーに提供されます。
• クライアント Blazor WebAssembly アプリは、サーバー アプリの他の静的な Web アセットと共に、サーバーアプリの /bin/Release/{TARGET
FRAMEWORK}/publish/wwwroot フォルダーに発⾏されます。
• 2 つのアプリが⼀緒に展開されます。 ASP.NET Core アプリをホストできる Web サーバーが必要です。 ホストされている展開の場合、Visual
Studio には WebAssembly アプリ プロジェクト テンプレートが含まれており (dotnet new コマンドを使⽤する場合は blazorwasm テンプレー
ト)、 Hosted オプションが選択されています (dotnet new コマンドを使⽤する場合は -ho|--hosted)。
• スタンドアロン展開
• Blazor アプリは、Blazor アプリの提供に .NET が使⽤されていない静的ホスティング Web サーバーまたはサービス上に配置されます。
• "スタンドアロン デプロイ" により、 WebAssembly アプリが、クライアントによって直接要求される静的ファイルのセットとして提供されます。 任意の静
的ファイル サーバーで Blazor アプリを提供できます。
• スタンドアロンのデプロイアセットは、/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot フォルダーに発⾏されます。
• Azure App Service
• Blazor WebAssembly アプリは、Blazor 上でアプリをホストするために使⽤される Windows 上の Azure App Service にデプロイできます。
• スタンドアロンの Blazor WebAssembly アプリを Azure App Service for Linux にデプロイすることは、現在サポートされていません。 現時点で
は、アプリをホストする Linux サーバー イメージは使⽤できません。 このシナリオを可能にするための取り組みが進⾏中です。
• Azure Static Web Apps
• 詳細については、「Tutorial: Building a static web app with Blazor in Azure Static Web Apps」を参照してください。
• IIS
EC デモアプリの画⾯遷移例
トップ
検索
Movies Books Video Games
選択
カート
決済・ログイン
ユーザー登録
EC Demo アプリの構成 1
Azure
SQL Database
Elastic Cloud
東⽇本リージョン
マスターノード x 1
データノード x 2
ML ノード x 1
https://f79...c67.japaneast
.azure.elastic-
cloud.com:9243/
全⽂検索クエリ
検索・更新 UI
Azure サブスクリプション
Azure
App Service
Elastic APM
Endpoint に送信
Blazor
Server
APM .NET Agent
Blazor
WebAssembly
CRUD
Visual
Studio
2022 for
Mac Azure Data Studio
EC Demo アプリの構成 2
Azure
SQL Database
Elastic Cloud
東⽇本リージョン
マスターノード x 1
データノード x 2
ML ノード x 1
https://f79...c67.japaneast
.azure.elastic-
cloud.com:9243/
CRUD
Azure サブスクリプション
Visual
Studio
2022 for
Mac
Azure
App Service
Elastic APM
Endpoint に送信
Azure Data Studio
ASP.NET 6 Web API
Azure
Static Web Apps
Blazor
WebAssembly
検索・更新 UI
APM .NET Agent
Blazor
WebAssembly
全⽂検索クエリ
ASP.NET Core Blazor
のホスティング モデル
https://docs.microsoft.com/ja-jp/aspnet/core/blazor/hosting-models?view=aspnetcore-6.0#blazor-webassembly
ホスティング モデルの選択
Blazor サーバー Blazor WebAssembly
完全な .NET Core API の互換性 ✔ ❌
サーバー ソースへの直接アクセス ✔ ❌
⼩さいペイロード サイズと
⾼速な初期読み込み時間
✔ ❌
サーバー上でのアプリ コードの
セキュリティ保護と⾮公開
✔ ❌†
ダウンロードしたアプリを
オフラインで実⾏
❌ ✔
静的サイトのホスティング ❌ ✔
クライアントへの処理のオフロード ❌ ✔
Blazor WebAssembly プロジェクト作成
Blazor WebAssembly プロジェクト⽣成
チェックを⼊れる︕
Product Model の追加
Product Model の追加
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BlazorEcommerce.Shared
{
public class Product
{
public int Id { get; set; }
public string Title { get; set; };
public string Description { get; set; };
public string ImageUrl { get; set; };
public decimal Price { get; set; }
}
}
---
@using BlazorEcommerce.Shared
---
ProductList.Razor の追加
ProductList.Razor の追加 1
<h3>ProductList</h3>
---
@code {
public static List<Product> Products = new List<Product>
{
new Product {
Id = "1",
Title = "The Hitchhiker's Guide to the Galaxy",
ImageUrl = "https://upload.wikimedia.org/wikipedia/en/b/bd/H2G2_UK_front_cover.jpg",
Description = "銀河ヒッチハイク・ガイド[注 1](HG2G、[1] HHGTTG、[2] H2G2、[3] tHGttGと表記することもある)は、ダグラス・アダムスが⽣み出したコメディ
SFフランチャイズである。1978年にBBC Radio 4で放送されたラジオコメディが原作で、その後、舞台、⼩説、コミック、1981年のテレビシリーズ、1984年のテキストベー
スのコンピュータゲーム、2005年の⻑編映画など、様々な形式で翻案されている。",
Price. = 9.99m
}
new Product {
Id = "2",
Title = "Ready Player One",
ImageUrl = "https://upload.wikimedia.org/wikipedia/en/a/a4/Ready_Player_One_cover.jpg",
Description = “「レディ・プレイヤー・ワン」は2011年に発表されたSF⼩説で、アメリカ⼈作家アーネスト・クラインのデビュー作である。2045年のディストピアを舞台
に、主⼈公のウェイド・ワッツが世界規模のバーチャルリアリティゲームのイースターエッグを探し、その発⾒によってゲーム製作者の財産を相続することになるというス
トーリーである。クラインは2010年6⽉、⼊札競争の末に本作の出版権をクラウン・パブリッシング・グループ(ランダムハウスの⼀部⾨)に売却した[1]。 本作は2011年8
⽉16⽇に出版された[2]。同⽇にはオーディオブックも発売されており、ナレーションは、章のひとつで少し触れているウィル・ウィートンである[3][4]。 20 2012年には
アメリカ図書館協会のヤングアダルト図書館サービス部⾨からアレックス賞を受賞し[5] 、2011年にはプロメテウス賞を 受賞した[6]。”,
Price. = 7.99m
}
new Product {
Id = "3",
Title = "Nineteen Eighty-Four”,
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/c/c3/1984first.jpg",
Description = “ Nineteen Eighty-Four(1984)は、イギリスの作家ジョージ・オーウェルが書いたディストピア社会SF⼩説であり、教訓的な物語である。1949年6⽉8
⽇にセッカー&ウォーバーグ社から出版され、オーウェルが⽣前に完成させた9冊⽬にして最後の著作となった。⺠主社会主義者であるオーウェルは、スターリン主義のロシ
アとナチス・ドイツをモデルに、⼩説の中の全体主義政府を描いた[2][3][4]。 より広く、この⼩説では政治における真実と事実の役割と、それらが操られる⽅法を検証し
ている。" ,
Price = 6.99m }
}
ProductList.Razor の追加 2
<h3>ProductList</h3>
<ul class="list-unstyled">
@foreach (var product in ProductService.Products)
{
<li class="media my-3">
<div class="media-img-wrapper mr-2">
<a href="/product/@product.Id">
<img class="media-img" src="@product.ImageUrl" alt="@product.Title" />
</a>
</div>
<div class="media-body">
<a href="/product/@product.Id">
<h4 class="mb-0">@product.Title</h4>
</a>
<p>@product.Description</p>
<h5 class="price">
@GetPriceText(product)
</h5>
</div>
</li>
}
</ul>
---
Index.Razor の変更
@page "/"
<ProductList />
https://localhost:7226/#
Web API コントローラー追加、モデル追加
API コントローラーの追加
ProductController.cs の追加 1
[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
{
private static List <Product> Products = new List <Product> {
new Product {
Id = "1",
Title = "The Hitchhiker's Guide to the Galaxy",
ImageUrl = "https://upload.wikimedia.org/wikipedia/en/b/bd/H2G2_UK_front_cover.jpg",
Description = "銀河ヒッチハイク・ガイド[注 1](HG2G、[1] HHGTTG、[2] H2G2、[3] tHGttGと表記することもある)は、ダグラス・アダムスが
⽣み出したコメディSFフランチャイズである。1978年にBBC Radio 4で放送されたラジオコメディが原作で、その後、舞台、⼩説、コミック、1981年の
テレビシリーズ、1984年のテキストベースのコンピュータゲーム、2005年の⻑編映画など、様々な形式で翻案されている。",
Price. = 9.99m
}
new Product {
Id = "2",
Title = "Ready Player One",
ImageUrl = "https://upload.wikimedia.org/wikipedia/en/a/a4/Ready_Player_One_cover.jpg",
Description = “「レディ・プレイヤー・ワン」は2011年に発表されたSF⼩説で、アメリカ⼈作家アーネスト・クラインのデビュー作である。2045年の
ディストピアを舞台に、主⼈公のウェイド・ワッツが世界規模のバーチャルリアリティゲームのイースターエッグを探し、その発⾒によってゲーム製作
者の財産を相続することになるというストーリーである。クラインは2010年6⽉、⼊札競争の末に本作の出版権をクラウン・パブリッシング・グループ
(ランダムハウスの⼀部⾨)に売却した[1]。 本作は2011年8⽉16⽇に出版された[2]。同⽇にはオーディオブックも発売されており、ナレーションは、
章のひとつで少し触れているウィル・ウィートンである[3][4]。2012年にはアメリカ図書館協会のヤングアダルト図書館サービス部⾨からアレックス賞
を受賞し[5] 、2011年にはプロメテウス賞を受賞した[6]。”,
Price. = 7.99m
}
new Product {
Id = "3",
Title = "Nineteen Eighty-Four”,
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/c/c3/1984first.jpg",
Description = “ Nineteen Eighty-Four(1984)は、イギリスの作家ジョージ・オーウェルが書いたディストピア社会SF⼩説であり、教訓的な物語
である。1949年6⽉8⽇にセッカー&ウォーバーグ社から出版され、オーウェルが⽣前に完成させた9冊⽬にして最後の著作となった。⺠主社会主義者で
あるオーウェルは、スターリン主義のロシアとナチス・ドイツをモデルに、⼩説の中の全体主義政府を描いた[2][3][4]。より広く、この⼩説では政治
における真実と事実の役割と、それらが操られる⽅法を検証している。" ,
Price = 6.99m }
}
---
ProductController.cs の追加 2
---
[HttpGet]
public async Task<ActionResult<<List<Product>>> GetProducts()
{
rerurn Ok(Product)
var result = await _productService. GetProductsAsync();
return Ok(result);
}
https://localhost:7226/#
ProductList.Razor の変更(クライアントからの呼び出し)
---
@inject HttpClient Http
<ul class="list-unstyled">
@foreach (var product in ProductService.Products)
{
<li class="media my-3">
<div class="media-img-wrapper mr-2">
<a href="/product/@product.Id">
<img class="media-img" src="@product.ImageUrl" alt="@product.Title" />
</a>
</div>
<div class="media-body">
<a href="/product/@product.Id">
<h4 class="mb-0">@product.Title</h4>
</a>
<p>@product.Description</p>
<h5 class="price">
@GetPriceText(product)
</h5>
</div>
</li>
}
</ul>
---
code@ {
private static List<Product> Products {get; set;} = new List<Product>();
protected override async TaskOnInitializedAsync()
{
Products = await Http.GetFromJsonAsync<List<Product>> ("api/product");
}
}
Entity Framework による Code First
データベース作成
Blazor アプリのデバッグその他の TIPS
dotnet watch run
public class xxx
prop → snippets が出て予測してくれる
swagger インストールその他
• https://localhost:(ポート番
号)/swagger/index.html
---
// AddRazorPages の後
builer.Services.AddEndpointApiExploler();
builer.Services.AddSwaggerGen();
//var ap = buildder.Build();の後
app.UserSwaggerUI();
// app.UseHttpsRedirection();の前
app.UseSwagger();
// Swagger UI で Products の shema が表⽰されない場合
// Public Async Task を書き換え
Task<Action> GetProduct()
→
Task<ActionResult<List<Product>>> GetProduct()
.NET Core Entity Framework 6.0 インストール
• Microsoft.EntityFrameworkCore
• Microsoft.EntityFrameworkCore.
Design
• Microsoft.EntityFrameworkCore.
SqlServer
• Mac の場合は、唯⼀の選択肢︕
Windows の場合は、SQL Server
Express Edition をインストールして使う
⼿もあり
appsettings.json で
”ConnectionString”
とうつと⾃動的に出てくる
この⽂字列をコピペして修正すればOK
※ 注意点
EF で Code First で Database を⾃動⽣成した場合、巨⼤なインスタンスになっ
ている(3⽇くらいで数千円レベル)。
instance のサイズだけはすぐに修正して⼩さいものBasic2TB等にする。
これなら⽉額数百円。
Azure SQL Database 接続⽂字列追加
{
"ConnectionStrings": {
"DefaultConnection":
"Server=tcp:xxx.database.windows.net,1433;Initial Catalog=BlazorEcommerce;Persist
Security Info=False;User ID=(UserID);Password=(Password);
MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
dotnet ef migration add CreateInitial // Migrations フォルダーと Migration クラス作成
dotnet ef Update Database // Azure SQL データベースとテーブル作成
Product Model の追加
• BlazorEcommerce.Shared フォルダに、
Product クラスを作成
• Book.cs に右のコードを記載
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BlazorEcommerce.Shared
{
public class Product
{
public int Id { get; set; }
[Required]
public string Title { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string ImageUrl { get; set; } = string.Empty;
public Category? Category { get; set; }
public int CategoryId { get; set; }
public bool Featured { get; set; } = false;
public List<ProductVariant> Variants { get; set; } =
new List<ProductVariant>();
public bool Visible { get; set; } = true;
public bool Deleted { get; set; } = false;
[NotMapped]
public bool Editing { get; set; } = false;
[NotMapped]
public bool IsNew { get; set; } = false;
}
}
DataContext 作成
• Class を追加
• DataContext.class
• Serverプロジェクト側の Program.cs
修正
• global using
Microsoft.EntityFramework.Core を⼊
れておくと楽
namespace BlazorEcommerce.Server.Data
{
public class DataContext : DbContext
{
// DataContext を作るのに ctor とタイプするとできる
// 全体的に IntelliCode が補完
public DataContext(DbContextOptions<DataContext>
options) : base(options)
{
}
}
}
• Server プロジェクト側の Program.cs
• DataContext.cs
global using Microsoft.EntityFrameworkCore;
Entity Framework を使った最初の DB Migration
//最初に名前を決めておく
dotnet ef migrations add CreateInitial
//成功したら Migration フォルダを開いて内容を確認
//データベース作成
dotnet ef database update
データのシード(2回⽬のマイグレーション)
---
Protected override void OnModelCreating(ModelBuilder
modelBuilder)
{
modelBuilder.Entity<Product>().HasData(
---<ここに new Product 3エントリをコピペ>---
);
}
dotnet ef migrations add ProductSeeding
dotnet ef database update
(参考)旧 ProductController.cs
[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
{
private static List <Product> Products = new List <Product> {
new Product {
Id = "1",
Title = "The Hitchhiker's Guide to the Galaxy",
ImageUrl = "https://upload.wikimedia.org/wikipedia/en/b/bd/H2G2_UK_front_cover.jpg",
Description = "銀河ヒッチハイク・ガイド[注 1](HG2G、[1] HHGTTG、[2] H2G2、[3] tHGttGと表記することもある)は、ダグラス・アダムスが
⽣み出したコメディSFフランチャイズである。1978年にBBC Radio 4で放送されたラジオコメディが原作で、その後、舞台、⼩説、コミック、1981年の
テレビシリーズ、1984年のテキストベースのコンピュータゲーム、2005年の⻑編映画など、様々な形式で翻案されている。",
Price. = 9.99m
}
new Product {
Id = "2",
Title = "Ready Player One",
ImageUrl = "https://upload.wikimedia.org/wikipedia/en/a/a4/Ready_Player_One_cover.jpg",
Description = “「レディ・プレイヤー・ワン」は2011年に発表されたSF⼩説で、アメリカ⼈作家アーネスト・クラインのデビュー作である。2045年の
ディストピアを舞台に、主⼈公のウェイド・ワッツが世界規模のバーチャルリアリティゲームのイースターエッグを探し、その発⾒によってゲーム製作
者の財産を相続することになるというストーリーである。クラインは2010年6⽉、⼊札競争の末に本作の出版権をクラウン・パブリッシング・グループ
(ランダムハウスの⼀部⾨)に売却した[1]。 本作は2011年8⽉16⽇に出版された[2]。同⽇にはオーディオブックも発売されており、ナレーションは、
章のひとつで少し触れているウィル・ウィートンである[3][4]。2012年にはアメリカ図書館協会のヤングアダルト図書館サービス部⾨からアレックス賞
を受賞し[5] 、2011年にはプロメテウス賞を受賞した[6]。”,
Price. = 7.99m
}
new Product {
Id = "3",
Title = "Nineteen Eighty-Four”,
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/c/c3/1984first.jpg",
Description = “ Nineteen Eighty-Four(1984)は、イギリスの作家ジョージ・オーウェルが書いたディストピア社会SF⼩説であり、教訓的な物語
である。1949年6⽉8⽇にセッカー&ウォーバーグ社から出版され、オーウェルが⽣前に完成させた9冊⽬にして最後の著作となった。⺠主社会主義者で
あるオーウェルは、スターリン主義のロシアとナチス・ドイツをモデルに、⼩説の中の全体主義政府を描いた[2][3][4]。より広く、この⼩説では政治
における真実と事実の役割と、それらが操られる⽅法を検証している。" ,
Price = 6.99m }
}
---
ProductController.cs 内のデータを削除
• Server Program.cs を開き global
using Blazorxxx.Server.Data; を追加
• private readonly DataContext
context;
⽣成されるので、これを修正
• しかしこれを⾃動的に実施したい
//context → _context に変更
public ProductController(DataContext context)
{
_cotext = context;
}
• Server プロジェクト側の Program.cs
global using Blazorxxx.Server.Data;
ツール → オプションから
テキストエディタ → C# → CodeStyle → Naming → Manage Naming Style
Naming Style Title : _fieldName
Capitalizatin : camel Case Name
これを追加したらprivate or internal Style に追加
_fieldName、Suggestion を選択
エディタに戻って create field context を選択する
[HttpGet] GetProduct() 変更
• ProductList
• ProductController
• DataContext
• [HttpGet] GetProduct() 変更
var products = await
_cotext.Products.ToListAsync();
return Ok(products)
商品サービス、商品リスト、カテゴリーサービス
等必要なサービス、CRUD 処理等の実装
Blazor WebAssembly の追加・改修等
• ProductDetail.razor.css 追加
• ProductDetail.razor 編集
@page "/product/{id:int}"
@inject IProductService ProductService
@inject ICartService CartService
Product 単品をクライアントで取得する
Category を実装する
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BlazorEcommerce.Shared
{
public class Category
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Url { get; set; } = string.Empty;
public bool Visible { get; set; } = true;
public bool Deleted { get; set; } = false;
[NotMapped]
public bool Editing { get; set; } = false;
[NotMapped]
public bool IsNew { get; set; } = false;
}
}
Category の Seeding と Migration(3回⽬)
•
•
---
modelBuilder.Entity<Category>().HasData(
new Category
{
Id = 1,
Name = "Books",
Url = "books"
},
new Category
{
Id = 2,
Name = "Movies",
Url = "movies"
},
new Category
{
Id = 3,
Name = "Video Games",
Url = "video-games"
}
);
---
• DataContext.cs
Category サービスの Client 側 への実装 - 1
•
•
namespace Blazorxxxxxxxx.Client.Services.CategoryService
{
public class CategoryService : ICategoryService
{
private readonly HttpClient _http;
public CategoryService(HttpClient http)
{
_http = http;
}
---
• CategoryServices.cs
Category サービスの Client 側 への実装 - 2
•
CategoryService
• global using で⼀番上に追加
//builder.Services.AddScoped<IProductService,ProductSe
rvice>();の下に追加
builder.Services.AddScoped<ICategoryService,
CategoryService>();
//⼀番上に追加
global using
Blazorxxxxxxxx.Client.Services.CategoryService;
• Program.cs
Category サービスの Client 側 への実装 - 3
•
@using Blazorxxxxxxxx.Client.Services.ProductService
• _Imports.razor
iCategoryServices の実装
•
namespace
Blazorxxxxxxx.Client.Services.CategoryService
{
public interface ICategoryService
{
event Action OnChange;
List<Category> Categories { get; set; }
List<Category> AdminCategories { get; set; }
Task GetCategories();
Task GetAdminCategories();
Task AddCategory(Category category);
Task UpdateCategory(Category category);
Task DeleteCategory(int categoryId);
Category CreateNewCategory();
}
}
• iCategoryServices.cs
NavMenu への Category の表⽰
• NavMenu.razor の編集
• @inject ICategoryService
CategoryService を冒頭に追加
• @code の後半部分に追加
• NavMenuCssClass の追加
protected override async Task OnInitializedAsync()
{
await CategoryService.GetCategories();
}
• NavMenu.razor
• NavMenuCssClass
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
Home
</NavLink>
</div>
@foreach (var category in CategoryService.Categories)
{
<div class="nav-item px-3">
<NavLink class="nav-link" href="@category.Url">
@category.Name
</NavLink>
</div>
}
</nav>
</div>
Server の Category サービスから Product を取得 - 1
•
•
Task<ServiceResponse<Product>> GetProduct(int productId);
• iProductService.cs
public async Task GetProducts(string? categoryUrl = null)
{
var result = categoryUrl == null ?
await
_http.GetFromJsonAsync<ServiceResponse
<List<Product>>>("api/product/featured") :
await _http.GetFromJsonAsync<ServiceResponse
<List<Product>>>($"api/product/category/{categoryUrl}");
if (result != null && result.Data != null)
Products = result.Data;
CurrentPage = 1;
PageCount = 0;
if (Products.Count == 0)
Message = "商品がみつかりません。";
ProductsChanged.Invoke();
}
• ProductService.cs
Server の Category サービスから Product を取得 - 2
•
•
• https://locahost:(ポート番
号)/swagger/index.html
---
[HttpGet("category/{categoryUrl}")]
public async Task<ActionResult<ServiceResponse
<List<Product>>>>
GetProductsByCategory(string categoryUrl)
{
var result =
await _productService.
GetProductsByCategory(categoryUrl);
return Ok(result);
}
---
• ProductController.cs
Client の Category サービスから Product を取得 - 1
•
• Task GetProducts を実装追加
• event ProductChanged を追加
•
public async Task GetProducts(string? categoryUrl = null)
{
var result = categoryUrl == null ?
//この2⾏がポイント
await _http.GetFromJsonAsync<ServiceResponse
<List<Product>>>("api/product/featured") :
await _http.GetFromJsonAsync<ServiceResponse
<List<Product>>>($"api/product/category/{categoryUrl}");
if (result != null && result.Data != null)
Products = result.Data;
CurrentPage = 1;
PageCount = 0;
if (Products.Count == 0)
Message = "商品がみつかりません。";
//ここもポイント
ProductsChanged.Invoke();
}
• iProductService.cs
• iProductService.cs
Task GetProducts(string? categoryUrl = null);
event Action ProductsChanged;
• iProductService.cs
Client の Category サービスから Product を取得 - 2
•
@page "/"
@page "/search/{searchText}/{page:int}"
@page "/{categoryUrl}"
@inject IProductService ProductService
<PageTitle>マイショップ</PageTitle>
@if (SearchText == null && CategoryUrl == null)
{
<FeaturedProducts />
}
else
{
<ProductList />
}
@code {
[Parameter]
public string? CategoryUrl { get; set; } = null;
[Parameter]
public string? SearchText { get; set; } = null;
[Parameter]
public int Page { get; set; } = 1;
protected override async Task OnParametersSetAsync()
{
if (SearchText != null)
{
await ProductService.SearchProducts(SearchText, Page);
}
else
{
await ProductService.GetProducts(CategoryUrl);
}
}
}
• Index.razor
Client の Category サービスから Product を取得 - 3
•
•
•
•
---
@code {
protected override void OnInitialized()
{
ProductService.ProductsChanged += StateHasChanged;
}
• ProductList.razor
---
public void Dispose()
{
ProductService.ProductsChanged -= StateHasChanged;
}
Shared に ProductVariant.cs を追加
•
•
•
• ProductVariant.cs
---
namespace BlazorEcommerce.Shared
{
public class ProductVariant
{
[JsonIgnore]
public Product? Product { get; set; }
public int ProductId { get; set; }
public ProductType? ProductType { get; set; }
public int ProductTypeId { get; set; }
[Column(TypeName = "decimal(18,2)")]
public decimal Price { get; set; }
[Column(TypeName = "decimal(18,2)")]
public decimal OriginalPrice { get; set; }
public bool Visible { get; set; } = true;
public bool Deleted { get; set; } = false;
[NotMapped]
public bool Editing { get; set; } = false;
[NotMapped]
public bool IsNew { get; set; } = false;
}
}
Composite Primary Key の追加と Seeding の実施(4回⽬)
•
•
•
•
• ProductTypes
• ProductVariants
---
modelBuilder.Entity<ProductVariant>().HasData(
new ProductVariant
{
ProductId = 1,
ProductTypeId = 2,
Price = 9.99m,
OriginalPrice = 19.99m
},
new ProductVariant
{
ProductId = 1,
ProductTypeId = 3,
Price = 7.99m
},
new ProductVariant
{
ProductId = 1,
ProductTypeId = 4,
Price = 19.99m,
OriginalPrice = 29.99m
},
new ProductVariant
{
ProductId = 2,
ProductTypeId = 2,
Price = 7.99m,
OriginalPrice = 14.99m
},
new ProductVariant
{
ProductId = 3,
ProductTypeId = 2,
Price = 6.99m
},
new ProductVariant
{
ProductId = 4,
ProductTypeId = 5,
Price = 3.99m
},
new ProductVariant
{
ProductId = 4,
ProductTypeId = 6,
Price = 9.99m
},
new ProductVariant
{
ProductId = 4,
ProductTypeId = 7,
Price = 19.99m
},
new ProductVariant
{
ProductId = 5,
ProductTypeId = 5,
Price = 3.99m,
},
new ProductVariant
{
ProductId = 6,
ProductTypeId = 5,
Price = 2.99m
},
new ProductVariant
{
ProductId = 7,
ProductTypeId = 8,
Price = 19.99m,
OriginalPrice = 29.99m
},
new ProductVariant
{
ProductId = 7,
ProductTypeId = 9,
Price = 69.99m
},
new ProductVariant
{
ProductId = 7,
ProductTypeId = 10,
Price = 49.99m,
OriginalPrice = 59.99m
},
new ProductVariant
{
ProductId = 8,
ProductTypeId = 8,
Price = 9.99m,
OriginalPrice = 24.99m,
},
new ProductVariant
{
ProductId = 9,
ProductTypeId = 8,
Price = 14.99m
},
new ProductVariant
{
ProductId = 10,
ProductTypeId = 1,
Price = 159.99m,
OriginalPrice = 299m
},
new ProductVariant
{
ProductId = 11,
ProductTypeId = 1,
Price = 79.99m,
OriginalPrice = 399m
}
);
}
---
Product Variants と Types を Product Service に含める - 1
•
•
• タブは Network
• フィルターは Fetch/XHR で実⾏
---
public async Task<ServiceResponse<Product>> GetProductAsync(int productId)
{
var response = new ServiceResponse<Product>();
Product product = null;
if (_httpContextAccessor.HttpContext.User.IsInRole("Admin"))
{
product = await _context.Products
.Include(p => p.Variants.Where(v => !v.Deleted))
.ThenInclude(v => v.ProductType)
.FirstOrDefaultAsync(p => p.Id == productId && !p.Deleted);
}
else
{
---
public async Task<ServiceResponse<List<Product>>> GetProductsAsync()
{
var response = new ServiceResponse<List<Product>>
{
Data = await _context.Products
.Where(p => p.Visible && !p.Deleted)
.Include(p => p.Variants.Where(v => v.Visible && !v.Deleted))
.ToListAsync()
---
public async Task<ServiceResponse
<List<Product>>> GetProductsByCategory(string categoryUrl)
{
var response = new ServiceResponse<List<Product>>
{
Data = await _context.Products
.Where(p => p.Category.Url.ToLower().Equals(categoryUrl.ToLower()) &&
p.Visible && !p.Deleted)
.Include(p => p.Variants.Where(v => v.Visible && !v.Deleted))
.ToListAsync()
---
Product Variants と Types を Product Service に含める - 2
•
• Productは取れている
• movies のところの下で Productを クリック
し、variants の中に Product が列挙される
ように出⼒されていることが確認できる
• id 指定してないと ProductType が⼊ってい
ないが、1と指定してリロード すると idに対応
した ProductType がちゃんと⼊っているの
が⾒える
まとめと次回の予定
まとめ
l 前回までの復習
l Blazor 概要
l 今回作成する Web アプリケーションの概要
l Blazor WebAssembly プロジェクト作成
l Web API コントローラー追加、モデル追加
l Entity Framework による Code First データベース作成
l 商品サービス、商品リスト、カテゴリーサービス等必要なサービス、CRUD 処理等の実装
l 検索サービスの追加と検索コンポーネントの実装
l カートサービス、認証・ユーザー登録
l その他の機能の実装と UI/UX の変更
リソースと今後の展望
l セッションでご紹介した EC アプリ .NET 5版ですが、参考にさせて戴きました。
l https://github.com/patrickgod/BlazorEcommercePreviewYT
l 4⽉は、検索サービス、カートサービス、認証・ユーザー登録、UI/UX 等
l 次回もよろしくお願いします︕
Thank you for your attention!
Elastic APM によるアプリケーションの監視
今回のデモアプリのイメージ
Azure
SQL Database
Elastic Cloud
東⽇本リージョン
マスターノード x 1
データノード x 2
ML ノード x 1
https://f79...c67.japaneast
.azure.elastic-
cloud.com:9243/
全⽂検索クエリ
CRUD
検索・更新 UI
APM .NET Agent
Blazor
WebAssembly
Azure サブスクリプション
Visual
Studio
2022
Azure
App Service
Elastic APM
Endpoint に送信
Azure
Data Explorer
ASP.NET 6
Web API
AntDesign
// .NETアプリへの Nuget パッケージインストール
dotnet add Elastic.Apm.NetCoreAll
Install-Package -ProjectName BlazorApp.Server -Id Elastic.Apm.NetCoreAll
Elastic APM for ASP
.NET Core
https://www.elastic.co/jp/apm/
Configuration on .NET Core
https://www.elastic.co/guide/en/apm/agent/dotnet/current/configuration-on-asp-net-core.html
ASP
.NET Core Quick Start
https://www.elastic.co/guide/en/apm/agent/dotnet/current/setup-asp-net-core.html
// Program.cs へ
の
追加
---
using Elastic.Apm.NetCoreAll;
//Elastic APM 追加
app.UseAllElasticApm(builder.Configuration);
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
---
// appsettings.json の
更新
---
{
"Logging": {
"LogLevel": {
//"Default": "Information",
//"Microsoft": "Warning",
//"Microsoft.Hosting.Lifetime": "Information"
"Default": "Warning",
"Elastic.Apm": "Debug"
}
} ,
"AllowedHosts": " * " ,
//Elastic ポ
ー
タ
ル
か
ら APM エ
ン
ド
ポ
イ
ン
ト
とSecret を
コ
ピ
ー
&
ペー
ス
ト
"ElasticApm": {
"ServerUrl":
"https://
7d39255475bg8e8e0j99fm870kj48v88.apm.
japaneast.azure.elastic-cloud.com",
"SecretToken": ”f6p81KJytBcGMK2JKS4",
"TransactionSampleRate": 1.0
}
}
Elastic Cloud → Kibana で APM モニタリング
https://cloud.elastic.co/home
その他の機能の実装と UI/UX の変更
AntDesign
• ⼈気 No.1 on
Awesome Blazor
• 企業向け製品のための
デザインシステム
• 効率的で楽しいワーク
エクスペリエンスを実現
https://antblazor.com/en-US/
Install-Package -ProjectName BlazorWASMApp.Client -Id AntDesign
AntDesign
• Components
• Image の使⽤⽅法を
参照
• Source Code 利⽤
可能
https://antblazor.com/en-US/components/image
まとめ
まとめ
l .NET 6 における Blazor Update
l ASP.NET Core Web API を構築
l Blazor WebAssembly でフロントエンドアプリを構築
l Elastic APM によるアプリケーションの監視
.NET MAUI Blazor App - モバイル、デスクトップ、
Web ハイブリッドアプリを開発
https://qiita.com/shosuz/items/4218af93343e5cc999ec
ASP.NET Core Blazor WebAssembly と Web API と Entity Framework
Core で SQL Server のデータを取得したり追加したり更新したり削除したりする
[.NET 6 版]
https://qiita.com/tamtamyarn/items/876a5cd4b9ec9cdc1044
Elastic リソース
• 公式ドキュメント
https://www.elastic.co/guide/index.html
• クラウドネイティブ アプリでの Elasticsearch
https://docs.microsoft.com/ja-jp/dotnet/architecture/cloud-
native/elastic-search-in-azure
• Azure での検索データ ストアの選択
https://docs.microsoft.com/ja-jp/azure/architecture/data-
guide/technology-choices/search-options
• Elastic APM Agent
https://www.elastic.co/guide/en/apm/agent/index.html
• APM
https://www.elastic.co/jp/apm/
• Configuration on .NET Core
https://www.elastic.co/guide/en/apm/agent/dotnet/current/co
nfiguration-on-asp-net-core.html
• ASP.NET Core Quick Start
https://www.elastic.co/guide/en/apm/agent/dotnet/current/set
up-asp-net-core.html
Thank you for your attention!

More Related Content

What's hot

Introduction to extensions and other useful features for developing apps usin...
Introduction to extensions and other useful features for developing apps usin...Introduction to extensions and other useful features for developing apps usin...
Introduction to extensions and other useful features for developing apps usin...Shotaro Suzuki
 
20210129 azure webapplogging
20210129 azure webapplogging20210129 azure webapplogging
20210129 azure webapploggingTakayoshi Tanaka
 
.NET 6の期待の新機能とアップデート
.NET 6の期待の新機能とアップデート.NET 6の期待の新機能とアップデート
.NET 6の期待の新機能とアップデートTomomitsuKusaba
 
MAF2013 Enterprise Windows 8 – Architecture for rapid development of WinRT apps
MAF2013 Enterprise Windows 8 – Architecture for rapid development of WinRT appsMAF2013 Enterprise Windows 8 – Architecture for rapid development of WinRT apps
MAF2013 Enterprise Windows 8 – Architecture for rapid development of WinRT appsShotaro Suzuki
 
コンテナ&サーバーレス:トレンドの考察と少し先の未来の展望
コンテナ&サーバーレス:トレンドの考察と少し先の未来の展望コンテナ&サーバーレス:トレンドの考察と少し先の未来の展望
コンテナ&サーバーレス:トレンドの考察と少し先の未来の展望Yoichi Kawasaki
 
Azure Api Management 俺的マニュアル 2020年3月版
Azure Api Management 俺的マニュアル 2020年3月版Azure Api Management 俺的マニュアル 2020年3月版
Azure Api Management 俺的マニュアル 2020年3月版貴志 上坂
 
Vs2013 multi device shosuz
Vs2013 multi device shosuzVs2013 multi device shosuz
Vs2013 multi device shosuzShotaro Suzuki
 
.NET の過去、現在、そして未来 ~ .NET 最新アップデート
.NET の過去、現在、そして未来 ~ .NET 最新アップデート.NET の過去、現在、そして未来 ~ .NET 最新アップデート
.NET の過去、現在、そして未来 ~ .NET 最新アップデートAkira Inoue
 
2021/03/19 パブリッククラウドを活かす運用プロセス自動化
2021/03/19 パブリッククラウドを活かす運用プロセス自動化2021/03/19 パブリッククラウドを活かす運用プロセス自動化
2021/03/19 パブリッククラウドを活かす運用プロセス自動化Issei Hiraoka
 
.NET の過去、現在、そして未来
.NET の過去、現在、そして未来.NET の過去、現在、そして未来
.NET の過去、現在、そして未来Akira Inoue
 
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web ServiceアプリケーションAngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーションssuser070fa9
 
CODT2020 ビジネスプラットフォームを支えるCI/CDパイプライン ~エンタープライズのDevOpsを加速させる運用改善Tips~
CODT2020 ビジネスプラットフォームを支えるCI/CDパイプライン ~エンタープライズのDevOpsを加速させる運用改善Tips~CODT2020 ビジネスプラットフォームを支えるCI/CDパイプライン ~エンタープライズのDevOpsを加速させる運用改善Tips~
CODT2020 ビジネスプラットフォームを支えるCI/CDパイプライン ~エンタープライズのDevOpsを加速させる運用改善Tips~Yuki Ando
 
進化する Web ~ Progressive Web Apps の実装と応用 ~
進化する Web  ~ Progressive Web Apps の実装と応用 ~進化する Web  ~ Progressive Web Apps の実装と応用 ~
進化する Web ~ Progressive Web Apps の実装と応用 ~Microsoft Azure Japan
 
Power app custom api v0.1.21.1221
Power app custom api v0.1.21.1221Power app custom api v0.1.21.1221
Power app custom api v0.1.21.1221Ayumu Inaba
 
レガシー Web からの脱却 ~ 開発者が次に目指すべき Web アプリの姿とは?
レガシー Web からの脱却 ~ 開発者が次に目指すべき Web アプリの姿とは?レガシー Web からの脱却 ~ 開発者が次に目指すべき Web アプリの姿とは?
レガシー Web からの脱却 ~ 開発者が次に目指すべき Web アプリの姿とは?Akira Inoue
 
Azure 高速サイトソリューション
Azure 高速サイトソリューションAzure 高速サイトソリューション
Azure 高速サイトソリューションHiromasa Oka
 
~ Build と言えば やっぱり Developer! ~ Microsoft 開発ツール最新アップデート
~ Build と言えば やっぱり Developer! ~ Microsoft 開発ツール最新アップデート~ Build と言えば やっぱり Developer! ~ Microsoft 開発ツール最新アップデート
~ Build と言えば やっぱり Developer! ~ Microsoft 開発ツール最新アップデートAkira Inoue
 
Javaプログラマーももう逃げられない。マイクロサービスとAPIの世界。
Javaプログラマーももう逃げられない。マイクロサービスとAPIの世界。Javaプログラマーももう逃げられない。マイクロサービスとAPIの世界。
Javaプログラマーももう逃げられない。マイクロサービスとAPIの世界。Takakiyo Tanaka
 
[DO07] マイクロサービスに必要な技術要素はすべて Spring Cloud にある
[DO07] マイクロサービスに必要な技術要素はすべて Spring Cloud にある[DO07] マイクロサービスに必要な技術要素はすべて Spring Cloud にある
[DO07] マイクロサービスに必要な技術要素はすべて Spring Cloud にあるde:code 2017
 
APIモック3分クッキング
APIモック3分クッキングAPIモック3分クッキング
APIモック3分クッキング政雄 金森
 

What's hot (20)

Introduction to extensions and other useful features for developing apps usin...
Introduction to extensions and other useful features for developing apps usin...Introduction to extensions and other useful features for developing apps usin...
Introduction to extensions and other useful features for developing apps usin...
 
20210129 azure webapplogging
20210129 azure webapplogging20210129 azure webapplogging
20210129 azure webapplogging
 
.NET 6の期待の新機能とアップデート
.NET 6の期待の新機能とアップデート.NET 6の期待の新機能とアップデート
.NET 6の期待の新機能とアップデート
 
MAF2013 Enterprise Windows 8 – Architecture for rapid development of WinRT apps
MAF2013 Enterprise Windows 8 – Architecture for rapid development of WinRT appsMAF2013 Enterprise Windows 8 – Architecture for rapid development of WinRT apps
MAF2013 Enterprise Windows 8 – Architecture for rapid development of WinRT apps
 
コンテナ&サーバーレス:トレンドの考察と少し先の未来の展望
コンテナ&サーバーレス:トレンドの考察と少し先の未来の展望コンテナ&サーバーレス:トレンドの考察と少し先の未来の展望
コンテナ&サーバーレス:トレンドの考察と少し先の未来の展望
 
Azure Api Management 俺的マニュアル 2020年3月版
Azure Api Management 俺的マニュアル 2020年3月版Azure Api Management 俺的マニュアル 2020年3月版
Azure Api Management 俺的マニュアル 2020年3月版
 
Vs2013 multi device shosuz
Vs2013 multi device shosuzVs2013 multi device shosuz
Vs2013 multi device shosuz
 
.NET の過去、現在、そして未来 ~ .NET 最新アップデート
.NET の過去、現在、そして未来 ~ .NET 最新アップデート.NET の過去、現在、そして未来 ~ .NET 最新アップデート
.NET の過去、現在、そして未来 ~ .NET 最新アップデート
 
2021/03/19 パブリッククラウドを活かす運用プロセス自動化
2021/03/19 パブリッククラウドを活かす運用プロセス自動化2021/03/19 パブリッククラウドを活かす運用プロセス自動化
2021/03/19 パブリッククラウドを活かす運用プロセス自動化
 
.NET の過去、現在、そして未来
.NET の過去、現在、そして未来.NET の過去、現在、そして未来
.NET の過去、現在、そして未来
 
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web ServiceアプリケーションAngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
 
CODT2020 ビジネスプラットフォームを支えるCI/CDパイプライン ~エンタープライズのDevOpsを加速させる運用改善Tips~
CODT2020 ビジネスプラットフォームを支えるCI/CDパイプライン ~エンタープライズのDevOpsを加速させる運用改善Tips~CODT2020 ビジネスプラットフォームを支えるCI/CDパイプライン ~エンタープライズのDevOpsを加速させる運用改善Tips~
CODT2020 ビジネスプラットフォームを支えるCI/CDパイプライン ~エンタープライズのDevOpsを加速させる運用改善Tips~
 
進化する Web ~ Progressive Web Apps の実装と応用 ~
進化する Web  ~ Progressive Web Apps の実装と応用 ~進化する Web  ~ Progressive Web Apps の実装と応用 ~
進化する Web ~ Progressive Web Apps の実装と応用 ~
 
Power app custom api v0.1.21.1221
Power app custom api v0.1.21.1221Power app custom api v0.1.21.1221
Power app custom api v0.1.21.1221
 
レガシー Web からの脱却 ~ 開発者が次に目指すべき Web アプリの姿とは?
レガシー Web からの脱却 ~ 開発者が次に目指すべき Web アプリの姿とは?レガシー Web からの脱却 ~ 開発者が次に目指すべき Web アプリの姿とは?
レガシー Web からの脱却 ~ 開発者が次に目指すべき Web アプリの姿とは?
 
Azure 高速サイトソリューション
Azure 高速サイトソリューションAzure 高速サイトソリューション
Azure 高速サイトソリューション
 
~ Build と言えば やっぱり Developer! ~ Microsoft 開発ツール最新アップデート
~ Build と言えば やっぱり Developer! ~ Microsoft 開発ツール最新アップデート~ Build と言えば やっぱり Developer! ~ Microsoft 開発ツール最新アップデート
~ Build と言えば やっぱり Developer! ~ Microsoft 開発ツール最新アップデート
 
Javaプログラマーももう逃げられない。マイクロサービスとAPIの世界。
Javaプログラマーももう逃げられない。マイクロサービスとAPIの世界。Javaプログラマーももう逃げられない。マイクロサービスとAPIの世界。
Javaプログラマーももう逃げられない。マイクロサービスとAPIの世界。
 
[DO07] マイクロサービスに必要な技術要素はすべて Spring Cloud にある
[DO07] マイクロサービスに必要な技術要素はすべて Spring Cloud にある[DO07] マイクロサービスに必要な技術要素はすべて Spring Cloud にある
[DO07] マイクロサービスに必要な技術要素はすべて Spring Cloud にある
 
APIモック3分クッキング
APIモック3分クッキングAPIモック3分クッキング
APIモック3分クッキング
 

Similar to Application development with c#, .net 6, blazor web assembly, asp.net web api, azure, part 2

Application development with c#, .net 6, blazor web assembly, asp.net web api...
Application development with c#, .net 6, blazor web assembly, asp.net web api...Application development with c#, .net 6, blazor web assembly, asp.net web api...
Application development with c#, .net 6, blazor web assembly, asp.net web api...Shotaro Suzuki
 
Application development with c#, .net 6, blazor web assembly, asp.net web api...
Application development with c#, .net 6, blazor web assembly, asp.net web api...Application development with c#, .net 6, blazor web assembly, asp.net web api...
Application development with c#, .net 6, blazor web assembly, asp.net web api...Shotaro Suzuki
 
New Features of DotNet 6 Blazor WASM
New Features of DotNet 6 Blazor WASMNew Features of DotNet 6 Blazor WASM
New Features of DotNet 6 Blazor WASMShotaro Suzuki
 
.NET 6 と Blazor で作るクロスプラットフォームアプリ概要
.NET 6 と Blazor で作るクロスプラットフォームアプリ概要.NET 6 と Blazor で作るクロスプラットフォームアプリ概要
.NET 6 と Blazor で作るクロスプラットフォームアプリ概要Akira Inoue
 
【de:code 2020】 「あつまれ フロントエンドエンジニア」 Azure Static Web Apps がやってきた
【de:code 2020】 「あつまれ フロントエンドエンジニア」 Azure Static Web Apps がやってきた【de:code 2020】 「あつまれ フロントエンドエンジニア」 Azure Static Web Apps がやってきた
【de:code 2020】 「あつまれ フロントエンドエンジニア」 Azure Static Web Apps がやってきた日本マイクロソフト株式会社
 
【BS14】Blazor WebAssemblyとJavaScriptのインターオペラビリティ
【BS14】Blazor WebAssemblyとJavaScriptのインターオペラビリティ 【BS14】Blazor WebAssemblyとJavaScriptのインターオペラビリティ
【BS14】Blazor WebAssemblyとJavaScriptのインターオペラビリティ 日本マイクロソフト株式会社
 
ASP.NET vNext / Visual Studio "14" に見る .NET の未来像
ASP.NET vNext / Visual Studio "14" に見る .NET の未来像ASP.NET vNext / Visual Studio "14" に見る .NET の未来像
ASP.NET vNext / Visual Studio "14" に見る .NET の未来像Akira Inoue
 
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説Akira Inoue
 
Cloud から IoT まで、なんでもおまかせ ~ .NET 5 正式リリース!
Cloud から IoT まで、なんでもおまかせ ~ .NET 5 正式リリース!Cloud から IoT まで、なんでもおまかせ ~ .NET 5 正式リリース!
Cloud から IoT まで、なんでもおまかせ ~ .NET 5 正式リリース!Akira Inoue
 
[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践
[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践
[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践de:code 2017
 
本格化するクラウド ネイティブに向けて進化する開発プラットフォームと .NET
本格化するクラウド ネイティブに向けて進化する開発プラットフォームと .NET本格化するクラウド ネイティブに向けて進化する開発プラットフォームと .NET
本格化するクラウド ネイティブに向けて進化する開発プラットフォームと .NETAkira Inoue
 
【de:code 2020】 Build 2020 最新情報 〜 Azure & Visual Studio & .NET 〜
【de:code 2020】 Build 2020 最新情報 〜 Azure & Visual Studio & .NET 〜【de:code 2020】 Build 2020 最新情報 〜 Azure & Visual Studio & .NET 〜
【de:code 2020】 Build 2020 最新情報 〜 Azure & Visual Studio & .NET 〜日本マイクロソフト株式会社
 
WebMatrix 2 と Azure Web Sites を使ったスマートフォンサイト構築のすすめ
WebMatrix 2 と Azure Web Sites を使ったスマートフォンサイト構築のすすめWebMatrix 2 と Azure Web Sites を使ったスマートフォンサイト構築のすすめ
WebMatrix 2 と Azure Web Sites を使ったスマートフォンサイト構築のすすめAkira Inoue
 
WebMatrix 2 と Azure を使ったスマートフォンサイト構築のすすめ
WebMatrix 2 と Azure を使ったスマートフォンサイト構築のすすめWebMatrix 2 と Azure を使ったスマートフォンサイト構築のすすめ
WebMatrix 2 と Azure を使ったスマートフォンサイト構築のすすめAkira Inoue
 
.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して
.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して
.NET の今と未来 ~ デバイス&クラウド ネイティブを目指してAkira Inoue
 
サーバー管理よ、サヨウナラ。サーバーレス アーキテクチャの意義と実践
サーバー管理よ、サヨウナラ。サーバーレス アーキテクチャの意義と実践サーバー管理よ、サヨウナラ。サーバーレス アーキテクチャの意義と実践
サーバー管理よ、サヨウナラ。サーバーレス アーキテクチャの意義と実践真吾 吉田
 
One ASP.NET ~ 今、ASP.NET に何が起こっているのか? ~
One ASP.NET ~ 今、ASP.NET に何が起こっているのか? ~One ASP.NET ~ 今、ASP.NET に何が起こっているのか? ~
One ASP.NET ~ 今、ASP.NET に何が起こっているのか? ~Akira Inoue
 
.NET Core 3.0 で Blazor を使用した​フルスタック C# Web アプリ​の構築
.NET Core 3.0 で Blazor を使用した​フルスタック C# Web アプリ​の構築.NET Core 3.0 で Blazor を使用した​フルスタック C# Web アプリ​の構築
.NET Core 3.0 で Blazor を使用した​フルスタック C# Web アプリ​の構築Joni
 

Similar to Application development with c#, .net 6, blazor web assembly, asp.net web api, azure, part 2 (20)

Application development with c#, .net 6, blazor web assembly, asp.net web api...
Application development with c#, .net 6, blazor web assembly, asp.net web api...Application development with c#, .net 6, blazor web assembly, asp.net web api...
Application development with c#, .net 6, blazor web assembly, asp.net web api...
 
Application development with c#, .net 6, blazor web assembly, asp.net web api...
Application development with c#, .net 6, blazor web assembly, asp.net web api...Application development with c#, .net 6, blazor web assembly, asp.net web api...
Application development with c#, .net 6, blazor web assembly, asp.net web api...
 
New Features of DotNet 6 Blazor WASM
New Features of DotNet 6 Blazor WASMNew Features of DotNet 6 Blazor WASM
New Features of DotNet 6 Blazor WASM
 
.NET 6 と Blazor で作るクロスプラットフォームアプリ概要
.NET 6 と Blazor で作るクロスプラットフォームアプリ概要.NET 6 と Blazor で作るクロスプラットフォームアプリ概要
.NET 6 と Blazor で作るクロスプラットフォームアプリ概要
 
[Japan Tech summit 2017] APP 001
[Japan Tech summit 2017] APP 001[Japan Tech summit 2017] APP 001
[Japan Tech summit 2017] APP 001
 
【de:code 2020】 「あつまれ フロントエンドエンジニア」 Azure Static Web Apps がやってきた
【de:code 2020】 「あつまれ フロントエンドエンジニア」 Azure Static Web Apps がやってきた【de:code 2020】 「あつまれ フロントエンドエンジニア」 Azure Static Web Apps がやってきた
【de:code 2020】 「あつまれ フロントエンドエンジニア」 Azure Static Web Apps がやってきた
 
【BS14】Blazor WebAssemblyとJavaScriptのインターオペラビリティ
【BS14】Blazor WebAssemblyとJavaScriptのインターオペラビリティ 【BS14】Blazor WebAssemblyとJavaScriptのインターオペラビリティ
【BS14】Blazor WebAssemblyとJavaScriptのインターオペラビリティ
 
ASP.NET vNext / Visual Studio "14" に見る .NET の未来像
ASP.NET vNext / Visual Studio "14" に見る .NET の未来像ASP.NET vNext / Visual Studio "14" に見る .NET の未来像
ASP.NET vNext / Visual Studio "14" に見る .NET の未来像
 
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
 
【BS2】.NET 6 最新アップデート
【BS2】.NET 6 最新アップデート【BS2】.NET 6 最新アップデート
【BS2】.NET 6 最新アップデート
 
Cloud から IoT まで、なんでもおまかせ ~ .NET 5 正式リリース!
Cloud から IoT まで、なんでもおまかせ ~ .NET 5 正式リリース!Cloud から IoT まで、なんでもおまかせ ~ .NET 5 正式リリース!
Cloud から IoT まで、なんでもおまかせ ~ .NET 5 正式リリース!
 
[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践
[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践
[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践
 
本格化するクラウド ネイティブに向けて進化する開発プラットフォームと .NET
本格化するクラウド ネイティブに向けて進化する開発プラットフォームと .NET本格化するクラウド ネイティブに向けて進化する開発プラットフォームと .NET
本格化するクラウド ネイティブに向けて進化する開発プラットフォームと .NET
 
【de:code 2020】 Build 2020 最新情報 〜 Azure & Visual Studio & .NET 〜
【de:code 2020】 Build 2020 最新情報 〜 Azure & Visual Studio & .NET 〜【de:code 2020】 Build 2020 最新情報 〜 Azure & Visual Studio & .NET 〜
【de:code 2020】 Build 2020 最新情報 〜 Azure & Visual Studio & .NET 〜
 
WebMatrix 2 と Azure Web Sites を使ったスマートフォンサイト構築のすすめ
WebMatrix 2 と Azure Web Sites を使ったスマートフォンサイト構築のすすめWebMatrix 2 と Azure Web Sites を使ったスマートフォンサイト構築のすすめ
WebMatrix 2 と Azure Web Sites を使ったスマートフォンサイト構築のすすめ
 
WebMatrix 2 と Azure を使ったスマートフォンサイト構築のすすめ
WebMatrix 2 と Azure を使ったスマートフォンサイト構築のすすめWebMatrix 2 と Azure を使ったスマートフォンサイト構築のすすめ
WebMatrix 2 と Azure を使ったスマートフォンサイト構築のすすめ
 
.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して
.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して
.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して
 
サーバー管理よ、サヨウナラ。サーバーレス アーキテクチャの意義と実践
サーバー管理よ、サヨウナラ。サーバーレス アーキテクチャの意義と実践サーバー管理よ、サヨウナラ。サーバーレス アーキテクチャの意義と実践
サーバー管理よ、サヨウナラ。サーバーレス アーキテクチャの意義と実践
 
One ASP.NET ~ 今、ASP.NET に何が起こっているのか? ~
One ASP.NET ~ 今、ASP.NET に何が起こっているのか? ~One ASP.NET ~ 今、ASP.NET に何が起こっているのか? ~
One ASP.NET ~ 今、ASP.NET に何が起こっているのか? ~
 
.NET Core 3.0 で Blazor を使用した​フルスタック C# Web アプリ​の構築
.NET Core 3.0 で Blazor を使用した​フルスタック C# Web アプリ​の構築.NET Core 3.0 で Blazor を使用した​フルスタック C# Web アプリ​の構築
.NET Core 3.0 で Blazor を使用した​フルスタック C# Web アプリ​の構築
 

More from Shotaro Suzuki

This is how our first offline technical event in three years was able to succ...
This is how our first offline technical event in three years was able to succ...This is how our first offline technical event in three years was able to succ...
This is how our first offline technical event in three years was able to succ...Shotaro Suzuki
 
Introducing the new features of the Elastic 8.6 release.pdf
Introducing the new features of the Elastic 8.6 release.pdfIntroducing the new features of the Elastic 8.6 release.pdf
Introducing the new features of the Elastic 8.6 release.pdfShotaro Suzuki
 
NET MAUI for .NET 7 for iOS, Android app development
 NET MAUI for .NET 7 for iOS, Android app development  NET MAUI for .NET 7 for iOS, Android app development
NET MAUI for .NET 7 for iOS, Android app development Shotaro Suzuki
 
What's New in the Elastic 8.5 Release
What's New in the Elastic 8.5 ReleaseWhat's New in the Elastic 8.5 Release
What's New in the Elastic 8.5 ReleaseShotaro Suzuki
 
Centralized Observability for the Azure Ecosystem
Centralized Observability for the Azure EcosystemCentralized Observability for the Azure Ecosystem
Centralized Observability for the Azure EcosystemShotaro Suzuki
 
What's New in the Elastic 8.4 Release
What's New in the Elastic 8.4 ReleaseWhat's New in the Elastic 8.4 Release
What's New in the Elastic 8.4 ReleaseShotaro Suzuki
 
Power Apps x .NET ~ Transforming Business Applications with Fusion Development
Power Apps x .NET ~ Transforming Business Applications with Fusion DevelopmentPower Apps x .NET ~ Transforming Business Applications with Fusion Development
Power Apps x .NET ~ Transforming Business Applications with Fusion DevelopmentShotaro Suzuki
 
devreljapan2022evaadvoc-final.pdf
devreljapan2022evaadvoc-final.pdfdevreljapan2022evaadvoc-final.pdf
devreljapan2022evaadvoc-final.pdfShotaro Suzuki
 
elastic-mabl-co-webinar-20220729
elastic-mabl-co-webinar-20220729elastic-mabl-co-webinar-20220729
elastic-mabl-co-webinar-20220729Shotaro Suzuki
 
Discover what's new in the Elastic 8.3 release - Find, monitor, and protect e...
Discover what's new in the Elastic 8.3 release - Find, monitor, and protect e...Discover what's new in the Elastic 8.3 release - Find, monitor, and protect e...
Discover what's new in the Elastic 8.3 release - Find, monitor, and protect e...Shotaro Suzuki
 
Building a search experience with Elastic – Introducing Elastic's latest samp...
Building a search experience with Elastic – Introducing Elastic's latest samp...Building a search experience with Elastic – Introducing Elastic's latest samp...
Building a search experience with Elastic – Introducing Elastic's latest samp...Shotaro Suzuki
 
Developing .NET 6 Blazor WebAssemby apps with Radzen Blazor component library...
Developing .NET 6 Blazor WebAssemby apps with Radzen Blazor component library...Developing .NET 6 Blazor WebAssemby apps with Radzen Blazor component library...
Developing .NET 6 Blazor WebAssemby apps with Radzen Blazor component library...Shotaro Suzuki
 
Elastic x Microsoft Azure Integration Evolution - Integrated Monitoring for S...
Elastic x Microsoft Azure Integration Evolution - Integrated Monitoring for S...Elastic x Microsoft Azure Integration Evolution - Integrated Monitoring for S...
Elastic x Microsoft Azure Integration Evolution - Integrated Monitoring for S...Shotaro Suzuki
 
Building 3D mobile apps using Power Apps Mixed Reality controls, Azure SQL Da...
Building 3D mobile apps using Power Apps Mixed Reality controls, Azure SQL Da...Building 3D mobile apps using Power Apps Mixed Reality controls, Azure SQL Da...
Building 3D mobile apps using Power Apps Mixed Reality controls, Azure SQL Da...Shotaro Suzuki
 
What's New in the Elastic 8.2 Release - Seamless User Experience with Search -
What's New in the Elastic 8.2 Release - Seamless User Experience with Search -What's New in the Elastic 8.2 Release - Seamless User Experience with Search -
What's New in the Elastic 8.2 Release - Seamless User Experience with Search -Shotaro Suzuki
 
Building Software Reliability through Distributed Tracing.pdf
Building Software Reliability through Distributed Tracing.pdfBuilding Software Reliability through Distributed Tracing.pdf
Building Software Reliability through Distributed Tracing.pdfShotaro Suzuki
 
Building a Flutter Development Environment with VSCode and Useful Extensions
Building a Flutter Development Environment with VSCode and Useful ExtensionsBuilding a Flutter Development Environment with VSCode and Useful Extensions
Building a Flutter Development Environment with VSCode and Useful ExtensionsShotaro Suzuki
 
Introducing the elastic 8.0 release a new era of speed, scale, relevance, and...
Introducing the elastic 8.0 release a new era of speed, scale, relevance, and...Introducing the elastic 8.0 release a new era of speed, scale, relevance, and...
Introducing the elastic 8.0 release a new era of speed, scale, relevance, and...Shotaro Suzuki
 
Developers-Summit-2022_Improving-Digital-Customer-Experience-with-Enterprise_...
Developers-Summit-2022_Improving-Digital-Customer-Experience-with-Enterprise_...Developers-Summit-2022_Improving-Digital-Customer-Experience-with-Enterprise_...
Developers-Summit-2022_Improving-Digital-Customer-Experience-with-Enterprise_...Shotaro Suzuki
 
Firebase, Firestore Extension for Elastic App Search Integration-20220216
Firebase, Firestore Extension for Elastic App Search Integration-20220216Firebase, Firestore Extension for Elastic App Search Integration-20220216
Firebase, Firestore Extension for Elastic App Search Integration-20220216Shotaro Suzuki
 

More from Shotaro Suzuki (20)

This is how our first offline technical event in three years was able to succ...
This is how our first offline technical event in three years was able to succ...This is how our first offline technical event in three years was able to succ...
This is how our first offline technical event in three years was able to succ...
 
Introducing the new features of the Elastic 8.6 release.pdf
Introducing the new features of the Elastic 8.6 release.pdfIntroducing the new features of the Elastic 8.6 release.pdf
Introducing the new features of the Elastic 8.6 release.pdf
 
NET MAUI for .NET 7 for iOS, Android app development
 NET MAUI for .NET 7 for iOS, Android app development  NET MAUI for .NET 7 for iOS, Android app development
NET MAUI for .NET 7 for iOS, Android app development
 
What's New in the Elastic 8.5 Release
What's New in the Elastic 8.5 ReleaseWhat's New in the Elastic 8.5 Release
What's New in the Elastic 8.5 Release
 
Centralized Observability for the Azure Ecosystem
Centralized Observability for the Azure EcosystemCentralized Observability for the Azure Ecosystem
Centralized Observability for the Azure Ecosystem
 
What's New in the Elastic 8.4 Release
What's New in the Elastic 8.4 ReleaseWhat's New in the Elastic 8.4 Release
What's New in the Elastic 8.4 Release
 
Power Apps x .NET ~ Transforming Business Applications with Fusion Development
Power Apps x .NET ~ Transforming Business Applications with Fusion DevelopmentPower Apps x .NET ~ Transforming Business Applications with Fusion Development
Power Apps x .NET ~ Transforming Business Applications with Fusion Development
 
devreljapan2022evaadvoc-final.pdf
devreljapan2022evaadvoc-final.pdfdevreljapan2022evaadvoc-final.pdf
devreljapan2022evaadvoc-final.pdf
 
elastic-mabl-co-webinar-20220729
elastic-mabl-co-webinar-20220729elastic-mabl-co-webinar-20220729
elastic-mabl-co-webinar-20220729
 
Discover what's new in the Elastic 8.3 release - Find, monitor, and protect e...
Discover what's new in the Elastic 8.3 release - Find, monitor, and protect e...Discover what's new in the Elastic 8.3 release - Find, monitor, and protect e...
Discover what's new in the Elastic 8.3 release - Find, monitor, and protect e...
 
Building a search experience with Elastic – Introducing Elastic's latest samp...
Building a search experience with Elastic – Introducing Elastic's latest samp...Building a search experience with Elastic – Introducing Elastic's latest samp...
Building a search experience with Elastic – Introducing Elastic's latest samp...
 
Developing .NET 6 Blazor WebAssemby apps with Radzen Blazor component library...
Developing .NET 6 Blazor WebAssemby apps with Radzen Blazor component library...Developing .NET 6 Blazor WebAssemby apps with Radzen Blazor component library...
Developing .NET 6 Blazor WebAssemby apps with Radzen Blazor component library...
 
Elastic x Microsoft Azure Integration Evolution - Integrated Monitoring for S...
Elastic x Microsoft Azure Integration Evolution - Integrated Monitoring for S...Elastic x Microsoft Azure Integration Evolution - Integrated Monitoring for S...
Elastic x Microsoft Azure Integration Evolution - Integrated Monitoring for S...
 
Building 3D mobile apps using Power Apps Mixed Reality controls, Azure SQL Da...
Building 3D mobile apps using Power Apps Mixed Reality controls, Azure SQL Da...Building 3D mobile apps using Power Apps Mixed Reality controls, Azure SQL Da...
Building 3D mobile apps using Power Apps Mixed Reality controls, Azure SQL Da...
 
What's New in the Elastic 8.2 Release - Seamless User Experience with Search -
What's New in the Elastic 8.2 Release - Seamless User Experience with Search -What's New in the Elastic 8.2 Release - Seamless User Experience with Search -
What's New in the Elastic 8.2 Release - Seamless User Experience with Search -
 
Building Software Reliability through Distributed Tracing.pdf
Building Software Reliability through Distributed Tracing.pdfBuilding Software Reliability through Distributed Tracing.pdf
Building Software Reliability through Distributed Tracing.pdf
 
Building a Flutter Development Environment with VSCode and Useful Extensions
Building a Flutter Development Environment with VSCode and Useful ExtensionsBuilding a Flutter Development Environment with VSCode and Useful Extensions
Building a Flutter Development Environment with VSCode and Useful Extensions
 
Introducing the elastic 8.0 release a new era of speed, scale, relevance, and...
Introducing the elastic 8.0 release a new era of speed, scale, relevance, and...Introducing the elastic 8.0 release a new era of speed, scale, relevance, and...
Introducing the elastic 8.0 release a new era of speed, scale, relevance, and...
 
Developers-Summit-2022_Improving-Digital-Customer-Experience-with-Enterprise_...
Developers-Summit-2022_Improving-Digital-Customer-Experience-with-Enterprise_...Developers-Summit-2022_Improving-Digital-Customer-Experience-with-Enterprise_...
Developers-Summit-2022_Improving-Digital-Customer-Experience-with-Enterprise_...
 
Firebase, Firestore Extension for Elastic App Search Integration-20220216
Firebase, Firestore Extension for Elastic App Search Integration-20220216Firebase, Firestore Extension for Elastic App Search Integration-20220216
Firebase, Firestore Extension for Elastic App Search Integration-20220216
 

Application development with c#, .net 6, blazor web assembly, asp.net web api, azure, part 2

  • 1. C#, .NET 6, Blazor WebAssembly, ASP.NET Web API, Azure による アプリ開発 – その2 鈴⽊ 章太郎 Elastic テクニカルプロダクトマーケティングマネージャー/エバンジェリスト デジタル庁 省庁業務グループ ソリューションアーキテクト
  • 3. l 前回までの復習 l Blazor 概要 l 今回作成する Web アプリケーションの概要 l Blazor WebAssembly プロジェクト作成 l Web API コントローラー追加、モデル追加 l Entity Framework による Code First データベース作成 l 商品サービス、商品リスト、カテゴリーサービス等必要なサービス、 CRUD 処理等の実装 l 検索サービスの追加と検索コンポーネントの実装 l カートサービス、認証・ユーザー登録 l その他の機能の実装と UI/UX の変更 アジェンダ
  • 4. リソースと今後の展望 l セッションでご紹介した EC アプリ .NET 5版ですが、参考にさせて戴きました。 l https://github.com/patrickgod/BlazorEcommercePreviewYT l 3⽉は、EF 連携-DB ⽣成、各サービス実装、検索機能 (Elastic による強化)等 l 将来的に microservices 化などできるといいなと思っています(4⽉︖W) l 今回、共演した宝達さんがデモされた OpenShift へのデプロイ、さらに進めて、ARO (Azure Red Hat OpenShift)にデプロイも⾯⽩いかなと思っています。 l 次回もよろしくお願いします︕ 検索機能の実装の前までご説明し、カートサービス、認証、ユーザー登 録、等はもし可能であれば、次回に回させて戴きたく… UI/UX はどこの箇所にも含まれていますが、ページネーション等は別途 取り上げて次回⼊れます。
  • 6. Modern Web UI with .NET & Blazor Server WebAssembly Hybrid HTML、CSS、.NET、C#... JavaScript の代わりに Open Web 標準でアプリ開発 どこにでもホストできる
  • 7. MVC Razor Pages Blazor HTTP APIs SignalR Part of the ASP.NET Core family Web UI Services Worker gRPC SPA
  • 8. Blazor – .NET 5 まで Blazor Server Blazor WebAssembly DOM Blazor WebAssembly .NET Razor Components Blazor .NET Razor Components DOM SignalR ü DB アクセス含むサーバー機能へのフルアクセス ü ⾼速なスタートアップ ü コードがサーバーから離れない ü 古いブラウザとシンクライアントをサポート ü 永続的な接続が必要 ü UI の遅延が⾼い ü完全にクライアント側で実⾏ ü必要なサーバー コンポーネントなし ü静的サイトとしてホスト üオフラインで実⾏可能 ü⼤きなダウンロードサイズ üランタイムパフォーマンスの低下 Blazor Server (.NET 5) Blazor WebAssembly (.NET 5)
  • 9. Blazor – .NET 6 による強化 Blazor Server Blazor WebAssembly DOM Blazor WebAssembly .NET Razor Components Blazor .NET Razor Components DOM SignalR Blazor WebAssembly の事前 (AOT) コンパイル対応 Blazor WebAssembly アプリのダウンロードサイズの縮⼩ Error Boundaries Razor コンポーネント型の推論とジェネリック型の制約 動的コンポーネント プリレンダリング中の Blazor コンポーネント状態の永続性 Hot Reload, Native File Reference, 他多数 .NET 6
  • 10. Blazor Server と Blazor WebAssembly の 開発モデルの違い Blazor Server Blazor WebAssembly DOM Blazor WebAssembly .NET Razor Components Blazor .NET Razor Components DOM SignalR Blazor Server • 開発モデルは C/S 型に近い • DOM(ブラウザ UI)と Blazor ランタイム(仮想 DOM) がやりとりし UI 描画(差分更新) • 画⾯の⼊出⼒部分のみをリモートデスクトップのようにブラウザ 側に持ってきているとみなせる • SignalR(Web ソケット通信) • DB に直接アクセス可能 • Web アプリケーションを Client - Server 型に近いモデルで 開発可能 • Web サーバとの常時接続が必要 • サーバ側でリソース効率の⾼いアプリの作り⽅が必要 • Hot Reload Blazor WebAssembly • サンドボックス制限 • DB アクセス不可 → Native File Reference による ローカル DBアクセス • Web API を介して DB アクセス • 静的な Web サーバにホスト • アプリ全体がダウンロード(⼤きくなりがち) • DOM(ブラウザ UI)と Blazor ランタイム(仮想 DOM)がやりとりしUI 描画(差分更新)、ランタイム が Blazor アプリ(UI ロジック)とやりとりする • Hot Reload (デバッグなしで実⾏)
  • 11. Web Assembly(WASM) とは • Web ブラウザ上でバイナリコードを直接実⾏できる • 2019 年 12 ⽉ W3C 勧告、正式なウェブ標準に認定 • 様々な⾔語のバイナリコードを主要なブラウザのサンドボックス内で動作可能 • Web Assembly バイナリコードへのコンパイラなどのツールセットが必要 Edge Chrome Safari Firefox Web Assembly バイナリコード (W3C 標準技術) C++ WASM コンパイラ Rust WASM コンパイラ C WASM コンパイラ SQLite ソースコード(C) Rust ソースコード C++ ソースコード
  • 12. .NET 6 における Blazor WebAssembly 新機能 • 事前 (AOT) 実⾏コンパイル • カスタム要素 • ⼩規模なアプリサイズ • Native File Reference • Hot Reload • Component, .NET, HTML, CSS… …その他数⼗個の更新あり
  • 13. Blazor WebAssembly ⼩規模なアプリサイズ .NET 5 • Publish size: 1.7 MB .NET 6 • Publish size: 1.0 MB • ~40% size reduction
  • 14. Blazor WebAssembly のホスティング ASP.NET Blazor WebAssem bly APIs Globally distributed hosting Blazor WebAssem bly Serverless functions APIs App Services Azure Static Web Apps ASP.NET Globally distributed hosting Microservices Blazor WebAssembly APIs Blazor WebAssembly APIs
  • 15. Get started with Blazor • Go to https://blazor.net • Install the .NET SDK • .NET Conf 2021 https://www.dotnetconf.net/ • .NET Conf 2021 – videos/slides/demos https://github.com/dotnet-presentations/dotNETConf/tree/master/2021/MainEvent/Technical Visual Studio Visual Studio for Mac Visual Studio Code + C# extension
  • 17. ASP.NET Core Blazor プロジェクトの構造 https://docs.microsoft.com/ja-jp/aspnet/core/blazor/project-structure?view=aspnetcore-6.0 Blazor WebAssembly アプリの初期ファイルとディレクトリ構造 [Client] • Connected Service • Dependencies • Pages • Properties • Shared • wwwrooot • _imports.razor • App.razor • Program.cs [Server] • Connected Service • Dependencies • Controllers • Pages • Properties • appsettings.json • Program.cs [Shared] • Connected Service • Dependencies • WeatherForecast.cs
  • 18. ASP.NET Core Blazor のホスティング モデル https://docs.microsoft.com/ja-jp/aspnet/core/blazor/hosting-models?view=aspnetcore-6.0 • Blazor WebAssembly hosting model を使⽤すると、次のようになります。 • Blazor アプリ、その依存関係、.NET ランタイムが並⾏してブラウザーにダウンロードされます。 • アプリがブラウザー UI スレッド上で直接実⾏されます。 • 次の展開戦略がサポートされています。 • ASP.NET Core でのホストされた展開 • Blazor アプリは、ASP.NET Core アプリによって提供されます。 • "ホストされたデプロイ" により、 WebAssembly アプリが、Web サーバー上で実⾏されている ASP.NET Core アプリからブラウザーに提供されます。 • クライアント Blazor WebAssembly アプリは、サーバー アプリの他の静的な Web アセットと共に、サーバーアプリの /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot フォルダーに発⾏されます。 • 2 つのアプリが⼀緒に展開されます。 ASP.NET Core アプリをホストできる Web サーバーが必要です。 ホストされている展開の場合、Visual Studio には WebAssembly アプリ プロジェクト テンプレートが含まれており (dotnet new コマンドを使⽤する場合は blazorwasm テンプレー ト)、 Hosted オプションが選択されています (dotnet new コマンドを使⽤する場合は -ho|--hosted)。 • スタンドアロン展開 • Blazor アプリは、Blazor アプリの提供に .NET が使⽤されていない静的ホスティング Web サーバーまたはサービス上に配置されます。 • "スタンドアロン デプロイ" により、 WebAssembly アプリが、クライアントによって直接要求される静的ファイルのセットとして提供されます。 任意の静 的ファイル サーバーで Blazor アプリを提供できます。 • スタンドアロンのデプロイアセットは、/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot フォルダーに発⾏されます。 • Azure App Service • Blazor WebAssembly アプリは、Blazor 上でアプリをホストするために使⽤される Windows 上の Azure App Service にデプロイできます。 • スタンドアロンの Blazor WebAssembly アプリを Azure App Service for Linux にデプロイすることは、現在サポートされていません。 現時点で は、アプリをホストする Linux サーバー イメージは使⽤できません。 このシナリオを可能にするための取り組みが進⾏中です。 • Azure Static Web Apps • 詳細については、「Tutorial: Building a static web app with Blazor in Azure Static Web Apps」を参照してください。 • IIS
  • 19. EC デモアプリの画⾯遷移例 トップ 検索 Movies Books Video Games 選択 カート 決済・ログイン ユーザー登録
  • 20. EC Demo アプリの構成 1 Azure SQL Database Elastic Cloud 東⽇本リージョン マスターノード x 1 データノード x 2 ML ノード x 1 https://f79...c67.japaneast .azure.elastic- cloud.com:9243/ 全⽂検索クエリ 検索・更新 UI Azure サブスクリプション Azure App Service Elastic APM Endpoint に送信 Blazor Server APM .NET Agent Blazor WebAssembly CRUD Visual Studio 2022 for Mac Azure Data Studio
  • 21. EC Demo アプリの構成 2 Azure SQL Database Elastic Cloud 東⽇本リージョン マスターノード x 1 データノード x 2 ML ノード x 1 https://f79...c67.japaneast .azure.elastic- cloud.com:9243/ CRUD Azure サブスクリプション Visual Studio 2022 for Mac Azure App Service Elastic APM Endpoint に送信 Azure Data Studio ASP.NET 6 Web API Azure Static Web Apps Blazor WebAssembly 検索・更新 UI APM .NET Agent Blazor WebAssembly 全⽂検索クエリ
  • 22. ASP.NET Core Blazor のホスティング モデル https://docs.microsoft.com/ja-jp/aspnet/core/blazor/hosting-models?view=aspnetcore-6.0#blazor-webassembly ホスティング モデルの選択 Blazor サーバー Blazor WebAssembly 完全な .NET Core API の互換性 ✔ ❌ サーバー ソースへの直接アクセス ✔ ❌ ⼩さいペイロード サイズと ⾼速な初期読み込み時間 ✔ ❌ サーバー上でのアプリ コードの セキュリティ保護と⾮公開 ✔ ❌† ダウンロードしたアプリを オフラインで実⾏ ❌ ✔ 静的サイトのホスティング ❌ ✔ クライアントへの処理のオフロード ❌ ✔
  • 26. Product Model の追加 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BlazorEcommerce.Shared { public class Product { public int Id { get; set; } public string Title { get; set; }; public string Description { get; set; }; public string ImageUrl { get; set; }; public decimal Price { get; set; } } } --- @using BlazorEcommerce.Shared ---
  • 28. ProductList.Razor の追加 1 <h3>ProductList</h3> --- @code { public static List<Product> Products = new List<Product> { new Product { Id = "1", Title = "The Hitchhiker's Guide to the Galaxy", ImageUrl = "https://upload.wikimedia.org/wikipedia/en/b/bd/H2G2_UK_front_cover.jpg", Description = "銀河ヒッチハイク・ガイド[注 1](HG2G、[1] HHGTTG、[2] H2G2、[3] tHGttGと表記することもある)は、ダグラス・アダムスが⽣み出したコメディ SFフランチャイズである。1978年にBBC Radio 4で放送されたラジオコメディが原作で、その後、舞台、⼩説、コミック、1981年のテレビシリーズ、1984年のテキストベー スのコンピュータゲーム、2005年の⻑編映画など、様々な形式で翻案されている。", Price. = 9.99m } new Product { Id = "2", Title = "Ready Player One", ImageUrl = "https://upload.wikimedia.org/wikipedia/en/a/a4/Ready_Player_One_cover.jpg", Description = “「レディ・プレイヤー・ワン」は2011年に発表されたSF⼩説で、アメリカ⼈作家アーネスト・クラインのデビュー作である。2045年のディストピアを舞台 に、主⼈公のウェイド・ワッツが世界規模のバーチャルリアリティゲームのイースターエッグを探し、その発⾒によってゲーム製作者の財産を相続することになるというス トーリーである。クラインは2010年6⽉、⼊札競争の末に本作の出版権をクラウン・パブリッシング・グループ(ランダムハウスの⼀部⾨)に売却した[1]。 本作は2011年8 ⽉16⽇に出版された[2]。同⽇にはオーディオブックも発売されており、ナレーションは、章のひとつで少し触れているウィル・ウィートンである[3][4]。 20 2012年には アメリカ図書館協会のヤングアダルト図書館サービス部⾨からアレックス賞を受賞し[5] 、2011年にはプロメテウス賞を 受賞した[6]。”, Price. = 7.99m } new Product { Id = "3", Title = "Nineteen Eighty-Four”, ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/c/c3/1984first.jpg", Description = “ Nineteen Eighty-Four(1984)は、イギリスの作家ジョージ・オーウェルが書いたディストピア社会SF⼩説であり、教訓的な物語である。1949年6⽉8 ⽇にセッカー&ウォーバーグ社から出版され、オーウェルが⽣前に完成させた9冊⽬にして最後の著作となった。⺠主社会主義者であるオーウェルは、スターリン主義のロシ アとナチス・ドイツをモデルに、⼩説の中の全体主義政府を描いた[2][3][4]。 より広く、この⼩説では政治における真実と事実の役割と、それらが操られる⽅法を検証し ている。" , Price = 6.99m } }
  • 29. ProductList.Razor の追加 2 <h3>ProductList</h3> <ul class="list-unstyled"> @foreach (var product in ProductService.Products) { <li class="media my-3"> <div class="media-img-wrapper mr-2"> <a href="/product/@product.Id"> <img class="media-img" src="@product.ImageUrl" alt="@product.Title" /> </a> </div> <div class="media-body"> <a href="/product/@product.Id"> <h4 class="mb-0">@product.Title</h4> </a> <p>@product.Description</p> <h5 class="price"> @GetPriceText(product) </h5> </div> </li> } </ul> ---
  • 30. Index.Razor の変更 @page "/" <ProductList /> https://localhost:7226/#
  • 33. ProductController.cs の追加 1 [Route("api/[controller]")] [ApiController] public class ProductController : ControllerBase { private static List <Product> Products = new List <Product> { new Product { Id = "1", Title = "The Hitchhiker's Guide to the Galaxy", ImageUrl = "https://upload.wikimedia.org/wikipedia/en/b/bd/H2G2_UK_front_cover.jpg", Description = "銀河ヒッチハイク・ガイド[注 1](HG2G、[1] HHGTTG、[2] H2G2、[3] tHGttGと表記することもある)は、ダグラス・アダムスが ⽣み出したコメディSFフランチャイズである。1978年にBBC Radio 4で放送されたラジオコメディが原作で、その後、舞台、⼩説、コミック、1981年の テレビシリーズ、1984年のテキストベースのコンピュータゲーム、2005年の⻑編映画など、様々な形式で翻案されている。", Price. = 9.99m } new Product { Id = "2", Title = "Ready Player One", ImageUrl = "https://upload.wikimedia.org/wikipedia/en/a/a4/Ready_Player_One_cover.jpg", Description = “「レディ・プレイヤー・ワン」は2011年に発表されたSF⼩説で、アメリカ⼈作家アーネスト・クラインのデビュー作である。2045年の ディストピアを舞台に、主⼈公のウェイド・ワッツが世界規模のバーチャルリアリティゲームのイースターエッグを探し、その発⾒によってゲーム製作 者の財産を相続することになるというストーリーである。クラインは2010年6⽉、⼊札競争の末に本作の出版権をクラウン・パブリッシング・グループ (ランダムハウスの⼀部⾨)に売却した[1]。 本作は2011年8⽉16⽇に出版された[2]。同⽇にはオーディオブックも発売されており、ナレーションは、 章のひとつで少し触れているウィル・ウィートンである[3][4]。2012年にはアメリカ図書館協会のヤングアダルト図書館サービス部⾨からアレックス賞 を受賞し[5] 、2011年にはプロメテウス賞を受賞した[6]。”, Price. = 7.99m } new Product { Id = "3", Title = "Nineteen Eighty-Four”, ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/c/c3/1984first.jpg", Description = “ Nineteen Eighty-Four(1984)は、イギリスの作家ジョージ・オーウェルが書いたディストピア社会SF⼩説であり、教訓的な物語 である。1949年6⽉8⽇にセッカー&ウォーバーグ社から出版され、オーウェルが⽣前に完成させた9冊⽬にして最後の著作となった。⺠主社会主義者で あるオーウェルは、スターリン主義のロシアとナチス・ドイツをモデルに、⼩説の中の全体主義政府を描いた[2][3][4]。より広く、この⼩説では政治 における真実と事実の役割と、それらが操られる⽅法を検証している。" , Price = 6.99m } } ---
  • 34. ProductController.cs の追加 2 --- [HttpGet] public async Task<ActionResult<<List<Product>>> GetProducts() { rerurn Ok(Product) var result = await _productService. GetProductsAsync(); return Ok(result); } https://localhost:7226/#
  • 35. ProductList.Razor の変更(クライアントからの呼び出し) --- @inject HttpClient Http <ul class="list-unstyled"> @foreach (var product in ProductService.Products) { <li class="media my-3"> <div class="media-img-wrapper mr-2"> <a href="/product/@product.Id"> <img class="media-img" src="@product.ImageUrl" alt="@product.Title" /> </a> </div> <div class="media-body"> <a href="/product/@product.Id"> <h4 class="mb-0">@product.Title</h4> </a> <p>@product.Description</p> <h5 class="price"> @GetPriceText(product) </h5> </div> </li> } </ul> --- code@ { private static List<Product> Products {get; set;} = new List<Product>(); protected override async TaskOnInitializedAsync() { Products = await Http.GetFromJsonAsync<List<Product>> ("api/product"); } }
  • 36. Entity Framework による Code First データベース作成
  • 37. Blazor アプリのデバッグその他の TIPS dotnet watch run public class xxx prop → snippets が出て予測してくれる
  • 38. swagger インストールその他 • https://localhost:(ポート番 号)/swagger/index.html --- // AddRazorPages の後 builer.Services.AddEndpointApiExploler(); builer.Services.AddSwaggerGen(); //var ap = buildder.Build();の後 app.UserSwaggerUI(); // app.UseHttpsRedirection();の前 app.UseSwagger(); // Swagger UI で Products の shema が表⽰されない場合 // Public Async Task を書き換え Task<Action> GetProduct() → Task<ActionResult<List<Product>>> GetProduct()
  • 39. .NET Core Entity Framework 6.0 インストール • Microsoft.EntityFrameworkCore • Microsoft.EntityFrameworkCore. Design • Microsoft.EntityFrameworkCore. SqlServer • Mac の場合は、唯⼀の選択肢︕ Windows の場合は、SQL Server Express Edition をインストールして使う ⼿もあり appsettings.json で ”ConnectionString” とうつと⾃動的に出てくる この⽂字列をコピペして修正すればOK ※ 注意点 EF で Code First で Database を⾃動⽣成した場合、巨⼤なインスタンスになっ ている(3⽇くらいで数千円レベル)。 instance のサイズだけはすぐに修正して⼩さいものBasic2TB等にする。 これなら⽉額数百円。
  • 40. Azure SQL Database 接続⽂字列追加 { "ConnectionStrings": { "DefaultConnection": "Server=tcp:xxx.database.windows.net,1433;Initial Catalog=BlazorEcommerce;Persist Security Info=False;User ID=(UserID);Password=(Password); MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" } dotnet ef migration add CreateInitial // Migrations フォルダーと Migration クラス作成 dotnet ef Update Database // Azure SQL データベースとテーブル作成
  • 41. Product Model の追加 • BlazorEcommerce.Shared フォルダに、 Product クラスを作成 • Book.cs に右のコードを記載 using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BlazorEcommerce.Shared { public class Product { public int Id { get; set; } [Required] public string Title { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public string ImageUrl { get; set; } = string.Empty; public Category? Category { get; set; } public int CategoryId { get; set; } public bool Featured { get; set; } = false; public List<ProductVariant> Variants { get; set; } = new List<ProductVariant>(); public bool Visible { get; set; } = true; public bool Deleted { get; set; } = false; [NotMapped] public bool Editing { get; set; } = false; [NotMapped] public bool IsNew { get; set; } = false; } }
  • 42. DataContext 作成 • Class を追加 • DataContext.class • Serverプロジェクト側の Program.cs 修正 • global using Microsoft.EntityFramework.Core を⼊ れておくと楽 namespace BlazorEcommerce.Server.Data { public class DataContext : DbContext { // DataContext を作るのに ctor とタイプするとできる // 全体的に IntelliCode が補完 public DataContext(DbContextOptions<DataContext> options) : base(options) { } } } • Server プロジェクト側の Program.cs • DataContext.cs global using Microsoft.EntityFrameworkCore;
  • 43. Entity Framework を使った最初の DB Migration //最初に名前を決めておく dotnet ef migrations add CreateInitial //成功したら Migration フォルダを開いて内容を確認 //データベース作成 dotnet ef database update
  • 44. データのシード(2回⽬のマイグレーション) --- Protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Product>().HasData( ---<ここに new Product 3エントリをコピペ>--- ); } dotnet ef migrations add ProductSeeding dotnet ef database update
  • 45. (参考)旧 ProductController.cs [Route("api/[controller]")] [ApiController] public class ProductController : ControllerBase { private static List <Product> Products = new List <Product> { new Product { Id = "1", Title = "The Hitchhiker's Guide to the Galaxy", ImageUrl = "https://upload.wikimedia.org/wikipedia/en/b/bd/H2G2_UK_front_cover.jpg", Description = "銀河ヒッチハイク・ガイド[注 1](HG2G、[1] HHGTTG、[2] H2G2、[3] tHGttGと表記することもある)は、ダグラス・アダムスが ⽣み出したコメディSFフランチャイズである。1978年にBBC Radio 4で放送されたラジオコメディが原作で、その後、舞台、⼩説、コミック、1981年の テレビシリーズ、1984年のテキストベースのコンピュータゲーム、2005年の⻑編映画など、様々な形式で翻案されている。", Price. = 9.99m } new Product { Id = "2", Title = "Ready Player One", ImageUrl = "https://upload.wikimedia.org/wikipedia/en/a/a4/Ready_Player_One_cover.jpg", Description = “「レディ・プレイヤー・ワン」は2011年に発表されたSF⼩説で、アメリカ⼈作家アーネスト・クラインのデビュー作である。2045年の ディストピアを舞台に、主⼈公のウェイド・ワッツが世界規模のバーチャルリアリティゲームのイースターエッグを探し、その発⾒によってゲーム製作 者の財産を相続することになるというストーリーである。クラインは2010年6⽉、⼊札競争の末に本作の出版権をクラウン・パブリッシング・グループ (ランダムハウスの⼀部⾨)に売却した[1]。 本作は2011年8⽉16⽇に出版された[2]。同⽇にはオーディオブックも発売されており、ナレーションは、 章のひとつで少し触れているウィル・ウィートンである[3][4]。2012年にはアメリカ図書館協会のヤングアダルト図書館サービス部⾨からアレックス賞 を受賞し[5] 、2011年にはプロメテウス賞を受賞した[6]。”, Price. = 7.99m } new Product { Id = "3", Title = "Nineteen Eighty-Four”, ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/c/c3/1984first.jpg", Description = “ Nineteen Eighty-Four(1984)は、イギリスの作家ジョージ・オーウェルが書いたディストピア社会SF⼩説であり、教訓的な物語 である。1949年6⽉8⽇にセッカー&ウォーバーグ社から出版され、オーウェルが⽣前に完成させた9冊⽬にして最後の著作となった。⺠主社会主義者で あるオーウェルは、スターリン主義のロシアとナチス・ドイツをモデルに、⼩説の中の全体主義政府を描いた[2][3][4]。より広く、この⼩説では政治 における真実と事実の役割と、それらが操られる⽅法を検証している。" , Price = 6.99m } } ---
  • 46. ProductController.cs 内のデータを削除 • Server Program.cs を開き global using Blazorxxx.Server.Data; を追加 • private readonly DataContext context; ⽣成されるので、これを修正 • しかしこれを⾃動的に実施したい //context → _context に変更 public ProductController(DataContext context) { _cotext = context; } • Server プロジェクト側の Program.cs global using Blazorxxx.Server.Data; ツール → オプションから テキストエディタ → C# → CodeStyle → Naming → Manage Naming Style Naming Style Title : _fieldName Capitalizatin : camel Case Name これを追加したらprivate or internal Style に追加 _fieldName、Suggestion を選択 エディタに戻って create field context を選択する
  • 47. [HttpGet] GetProduct() 変更 • ProductList • ProductController • DataContext • [HttpGet] GetProduct() 変更 var products = await _cotext.Products.ToListAsync(); return Ok(products)
  • 49. Blazor WebAssembly の追加・改修等 • ProductDetail.razor.css 追加 • ProductDetail.razor 編集 @page "/product/{id:int}" @inject IProductService ProductService @inject ICartService CartService
  • 51. Category を実装する using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BlazorEcommerce.Shared { public class Category { public int Id { get; set; } public string Name { get; set; } = string.Empty; public string Url { get; set; } = string.Empty; public bool Visible { get; set; } = true; public bool Deleted { get; set; } = false; [NotMapped] public bool Editing { get; set; } = false; [NotMapped] public bool IsNew { get; set; } = false; } }
  • 52. Category の Seeding と Migration(3回⽬) • • --- modelBuilder.Entity<Category>().HasData( new Category { Id = 1, Name = "Books", Url = "books" }, new Category { Id = 2, Name = "Movies", Url = "movies" }, new Category { Id = 3, Name = "Video Games", Url = "video-games" } ); --- • DataContext.cs
  • 53. Category サービスの Client 側 への実装 - 1 • • namespace Blazorxxxxxxxx.Client.Services.CategoryService { public class CategoryService : ICategoryService { private readonly HttpClient _http; public CategoryService(HttpClient http) { _http = http; } --- • CategoryServices.cs
  • 54. Category サービスの Client 側 への実装 - 2 • CategoryService • global using で⼀番上に追加 //builder.Services.AddScoped<IProductService,ProductSe rvice>();の下に追加 builder.Services.AddScoped<ICategoryService, CategoryService>(); //⼀番上に追加 global using Blazorxxxxxxxx.Client.Services.CategoryService; • Program.cs
  • 55. Category サービスの Client 側 への実装 - 3 • @using Blazorxxxxxxxx.Client.Services.ProductService • _Imports.razor
  • 56. iCategoryServices の実装 • namespace Blazorxxxxxxx.Client.Services.CategoryService { public interface ICategoryService { event Action OnChange; List<Category> Categories { get; set; } List<Category> AdminCategories { get; set; } Task GetCategories(); Task GetAdminCategories(); Task AddCategory(Category category); Task UpdateCategory(Category category); Task DeleteCategory(int categoryId); Category CreateNewCategory(); } } • iCategoryServices.cs
  • 57. NavMenu への Category の表⽰ • NavMenu.razor の編集 • @inject ICategoryService CategoryService を冒頭に追加 • @code の後半部分に追加 • NavMenuCssClass の追加 protected override async Task OnInitializedAsync() { await CategoryService.GetCategories(); } • NavMenu.razor • NavMenuCssClass <div class="@NavMenuCssClass" @onclick="ToggleNavMenu"> <nav class="flex-column"> <div class="nav-item px-3"> <NavLink class="nav-link" href="" Match="NavLinkMatch.All"> Home </NavLink> </div> @foreach (var category in CategoryService.Categories) { <div class="nav-item px-3"> <NavLink class="nav-link" href="@category.Url"> @category.Name </NavLink> </div> } </nav> </div>
  • 58. Server の Category サービスから Product を取得 - 1 • • Task<ServiceResponse<Product>> GetProduct(int productId); • iProductService.cs public async Task GetProducts(string? categoryUrl = null) { var result = categoryUrl == null ? await _http.GetFromJsonAsync<ServiceResponse <List<Product>>>("api/product/featured") : await _http.GetFromJsonAsync<ServiceResponse <List<Product>>>($"api/product/category/{categoryUrl}"); if (result != null && result.Data != null) Products = result.Data; CurrentPage = 1; PageCount = 0; if (Products.Count == 0) Message = "商品がみつかりません。"; ProductsChanged.Invoke(); } • ProductService.cs
  • 59. Server の Category サービスから Product を取得 - 2 • • • https://locahost:(ポート番 号)/swagger/index.html --- [HttpGet("category/{categoryUrl}")] public async Task<ActionResult<ServiceResponse <List<Product>>>> GetProductsByCategory(string categoryUrl) { var result = await _productService. GetProductsByCategory(categoryUrl); return Ok(result); } --- • ProductController.cs
  • 60. Client の Category サービスから Product を取得 - 1 • • Task GetProducts を実装追加 • event ProductChanged を追加 • public async Task GetProducts(string? categoryUrl = null) { var result = categoryUrl == null ? //この2⾏がポイント await _http.GetFromJsonAsync<ServiceResponse <List<Product>>>("api/product/featured") : await _http.GetFromJsonAsync<ServiceResponse <List<Product>>>($"api/product/category/{categoryUrl}"); if (result != null && result.Data != null) Products = result.Data; CurrentPage = 1; PageCount = 0; if (Products.Count == 0) Message = "商品がみつかりません。"; //ここもポイント ProductsChanged.Invoke(); } • iProductService.cs • iProductService.cs Task GetProducts(string? categoryUrl = null); event Action ProductsChanged; • iProductService.cs
  • 61. Client の Category サービスから Product を取得 - 2 • @page "/" @page "/search/{searchText}/{page:int}" @page "/{categoryUrl}" @inject IProductService ProductService <PageTitle>マイショップ</PageTitle> @if (SearchText == null && CategoryUrl == null) { <FeaturedProducts /> } else { <ProductList /> } @code { [Parameter] public string? CategoryUrl { get; set; } = null; [Parameter] public string? SearchText { get; set; } = null; [Parameter] public int Page { get; set; } = 1; protected override async Task OnParametersSetAsync() { if (SearchText != null) { await ProductService.SearchProducts(SearchText, Page); } else { await ProductService.GetProducts(CategoryUrl); } } } • Index.razor
  • 62. Client の Category サービスから Product を取得 - 3 • • • • --- @code { protected override void OnInitialized() { ProductService.ProductsChanged += StateHasChanged; } • ProductList.razor --- public void Dispose() { ProductService.ProductsChanged -= StateHasChanged; }
  • 63. Shared に ProductVariant.cs を追加 • • • • ProductVariant.cs --- namespace BlazorEcommerce.Shared { public class ProductVariant { [JsonIgnore] public Product? Product { get; set; } public int ProductId { get; set; } public ProductType? ProductType { get; set; } public int ProductTypeId { get; set; } [Column(TypeName = "decimal(18,2)")] public decimal Price { get; set; } [Column(TypeName = "decimal(18,2)")] public decimal OriginalPrice { get; set; } public bool Visible { get; set; } = true; public bool Deleted { get; set; } = false; [NotMapped] public bool Editing { get; set; } = false; [NotMapped] public bool IsNew { get; set; } = false; } }
  • 64. Composite Primary Key の追加と Seeding の実施(4回⽬) • • • • • ProductTypes • ProductVariants --- modelBuilder.Entity<ProductVariant>().HasData( new ProductVariant { ProductId = 1, ProductTypeId = 2, Price = 9.99m, OriginalPrice = 19.99m }, new ProductVariant { ProductId = 1, ProductTypeId = 3, Price = 7.99m }, new ProductVariant { ProductId = 1, ProductTypeId = 4, Price = 19.99m, OriginalPrice = 29.99m }, new ProductVariant { ProductId = 2, ProductTypeId = 2, Price = 7.99m, OriginalPrice = 14.99m }, new ProductVariant { ProductId = 3, ProductTypeId = 2, Price = 6.99m }, new ProductVariant { ProductId = 4, ProductTypeId = 5, Price = 3.99m }, new ProductVariant { ProductId = 4, ProductTypeId = 6, Price = 9.99m }, new ProductVariant { ProductId = 4, ProductTypeId = 7, Price = 19.99m }, new ProductVariant { ProductId = 5, ProductTypeId = 5, Price = 3.99m, }, new ProductVariant { ProductId = 6, ProductTypeId = 5, Price = 2.99m }, new ProductVariant { ProductId = 7, ProductTypeId = 8, Price = 19.99m, OriginalPrice = 29.99m }, new ProductVariant { ProductId = 7, ProductTypeId = 9, Price = 69.99m }, new ProductVariant { ProductId = 7, ProductTypeId = 10, Price = 49.99m, OriginalPrice = 59.99m }, new ProductVariant { ProductId = 8, ProductTypeId = 8, Price = 9.99m, OriginalPrice = 24.99m, }, new ProductVariant { ProductId = 9, ProductTypeId = 8, Price = 14.99m }, new ProductVariant { ProductId = 10, ProductTypeId = 1, Price = 159.99m, OriginalPrice = 299m }, new ProductVariant { ProductId = 11, ProductTypeId = 1, Price = 79.99m, OriginalPrice = 399m } ); } ---
  • 65. Product Variants と Types を Product Service に含める - 1 • • • タブは Network • フィルターは Fetch/XHR で実⾏ --- public async Task<ServiceResponse<Product>> GetProductAsync(int productId) { var response = new ServiceResponse<Product>(); Product product = null; if (_httpContextAccessor.HttpContext.User.IsInRole("Admin")) { product = await _context.Products .Include(p => p.Variants.Where(v => !v.Deleted)) .ThenInclude(v => v.ProductType) .FirstOrDefaultAsync(p => p.Id == productId && !p.Deleted); } else { --- public async Task<ServiceResponse<List<Product>>> GetProductsAsync() { var response = new ServiceResponse<List<Product>> { Data = await _context.Products .Where(p => p.Visible && !p.Deleted) .Include(p => p.Variants.Where(v => v.Visible && !v.Deleted)) .ToListAsync() --- public async Task<ServiceResponse <List<Product>>> GetProductsByCategory(string categoryUrl) { var response = new ServiceResponse<List<Product>> { Data = await _context.Products .Where(p => p.Category.Url.ToLower().Equals(categoryUrl.ToLower()) && p.Visible && !p.Deleted) .Include(p => p.Variants.Where(v => v.Visible && !v.Deleted)) .ToListAsync() ---
  • 66. Product Variants と Types を Product Service に含める - 2 • • Productは取れている • movies のところの下で Productを クリック し、variants の中に Product が列挙される ように出⼒されていることが確認できる • id 指定してないと ProductType が⼊ってい ないが、1と指定してリロード すると idに対応 した ProductType がちゃんと⼊っているの が⾒える
  • 68. まとめ l 前回までの復習 l Blazor 概要 l 今回作成する Web アプリケーションの概要 l Blazor WebAssembly プロジェクト作成 l Web API コントローラー追加、モデル追加 l Entity Framework による Code First データベース作成 l 商品サービス、商品リスト、カテゴリーサービス等必要なサービス、CRUD 処理等の実装 l 検索サービスの追加と検索コンポーネントの実装 l カートサービス、認証・ユーザー登録 l その他の機能の実装と UI/UX の変更
  • 69. リソースと今後の展望 l セッションでご紹介した EC アプリ .NET 5版ですが、参考にさせて戴きました。 l https://github.com/patrickgod/BlazorEcommercePreviewYT l 4⽉は、検索サービス、カートサービス、認証・ユーザー登録、UI/UX 等 l 次回もよろしくお願いします︕
  • 70. Thank you for your attention!
  • 72. 今回のデモアプリのイメージ Azure SQL Database Elastic Cloud 東⽇本リージョン マスターノード x 1 データノード x 2 ML ノード x 1 https://f79...c67.japaneast .azure.elastic- cloud.com:9243/ 全⽂検索クエリ CRUD 検索・更新 UI APM .NET Agent Blazor WebAssembly Azure サブスクリプション Visual Studio 2022 Azure App Service Elastic APM Endpoint に送信 Azure Data Explorer ASP.NET 6 Web API AntDesign
  • 73. // .NETアプリへの Nuget パッケージインストール dotnet add Elastic.Apm.NetCoreAll Install-Package -ProjectName BlazorApp.Server -Id Elastic.Apm.NetCoreAll Elastic APM for ASP .NET Core https://www.elastic.co/jp/apm/ Configuration on .NET Core https://www.elastic.co/guide/en/apm/agent/dotnet/current/configuration-on-asp-net-core.html ASP .NET Core Quick Start https://www.elastic.co/guide/en/apm/agent/dotnet/current/setup-asp-net-core.html // Program.cs へ の 追加 --- using Elastic.Apm.NetCoreAll; //Elastic APM 追加 app.UseAllElasticApm(builder.Configuration); app.UseHttpsRedirection(); app.UseBlazorFrameworkFiles(); app.UseStaticFiles(); --- // appsettings.json の 更新 --- { "Logging": { "LogLevel": { //"Default": "Information", //"Microsoft": "Warning", //"Microsoft.Hosting.Lifetime": "Information" "Default": "Warning", "Elastic.Apm": "Debug" } } , "AllowedHosts": " * " , //Elastic ポ ー タ ル か ら APM エ ン ド ポ イ ン ト とSecret を コ ピ ー & ペー ス ト "ElasticApm": { "ServerUrl": "https:// 7d39255475bg8e8e0j99fm870kj48v88.apm. japaneast.azure.elastic-cloud.com", "SecretToken": ”f6p81KJytBcGMK2JKS4", "TransactionSampleRate": 1.0 } }
  • 74. Elastic Cloud → Kibana で APM モニタリング https://cloud.elastic.co/home
  • 76. AntDesign • ⼈気 No.1 on Awesome Blazor • 企業向け製品のための デザインシステム • 効率的で楽しいワーク エクスペリエンスを実現 https://antblazor.com/en-US/ Install-Package -ProjectName BlazorWASMApp.Client -Id AntDesign
  • 77. AntDesign • Components • Image の使⽤⽅法を 参照 • Source Code 利⽤ 可能 https://antblazor.com/en-US/components/image
  • 79. まとめ l .NET 6 における Blazor Update l ASP.NET Core Web API を構築 l Blazor WebAssembly でフロントエンドアプリを構築 l Elastic APM によるアプリケーションの監視
  • 80. .NET MAUI Blazor App - モバイル、デスクトップ、 Web ハイブリッドアプリを開発 https://qiita.com/shosuz/items/4218af93343e5cc999ec
  • 81. ASP.NET Core Blazor WebAssembly と Web API と Entity Framework Core で SQL Server のデータを取得したり追加したり更新したり削除したりする [.NET 6 版] https://qiita.com/tamtamyarn/items/876a5cd4b9ec9cdc1044
  • 82. Elastic リソース • 公式ドキュメント https://www.elastic.co/guide/index.html • クラウドネイティブ アプリでの Elasticsearch https://docs.microsoft.com/ja-jp/dotnet/architecture/cloud- native/elastic-search-in-azure • Azure での検索データ ストアの選択 https://docs.microsoft.com/ja-jp/azure/architecture/data- guide/technology-choices/search-options • Elastic APM Agent https://www.elastic.co/guide/en/apm/agent/index.html • APM https://www.elastic.co/jp/apm/ • Configuration on .NET Core https://www.elastic.co/guide/en/apm/agent/dotnet/current/co nfiguration-on-asp-net-core.html • ASP.NET Core Quick Start https://www.elastic.co/guide/en/apm/agent/dotnet/current/set up-asp-net-core.html
  • 83. Thank you for your attention!