Building a Walking Skeleton
Create Project
- Click
Blazor WebAssembly
- Click
ASP.NET Core hosted
. It will create Client, Server and Shared Projects.
Model
Create Product
-
[Column(TypeName = "decimal(18,2)")]
is for a decimal error on database. - When you use the
decimal
type in your variable, you should set a scale of decimal. -
Because the flotting point can make a misunderstand in memory.
- BlazorEcommerce.Shared/Product.cs
Database
Packages in Server
- Download
Microsoft.EntityFrameworkCore
,Microsoft.EntityFrameworkCore.Design
andMicrosoft.EntityframeworkCore.Sqlserver
from Nuget Packages. - Install dotnet ef with a command
dotnet tool install --global dotnet-ef
.
Data Context
- BlazorEcommerce.Server/Data/DataContext.cs
Set Database
- BlazorEcommerce.Server/appsettings.json
-
Add information about database to server program.
-
BlazorEcommerce.Server/Program.cs
Update Database
- In console, tpye
dotnet ef migrations add CreateInitial
anddotnet ef database update
.
Controller
- You can your own web Api on Controller.
- Send and retuen data is json type.
- When you create new controller, click
API Controller - Empty
.
- BlazorEcommerce.Server/Controllers/ProductController.cs
Swagger
Package in Server
- Download
Swashbuckle.AspNetCore
from Nuget Packages.
Set
- BlazorEcommerce.Server/Program.cs
Run
- Change Url to
.../swagger/index.html
.
Show Products
Create ProductList Component
- Razor file is for view.
- BlazorEcommerce.Client/Shared/ProductList.razor
- cs file is for code.
- BlazorEcommerce.Client/Shared/ProductList.razor.cs
- css file is for design.
- BlazorEcommerce.Client/Shared/ProductList.razor.css
Add ProductList Component on Index
- BlazorEcommerce.Client/Shared/ProductList.razor
Run
Naming Options
- Click
Tools
-Options
-Text Editor
-C#
-Code Style
-Naming
. - To create a new naming Style, click
Manage naming styles
.
Products
Models for Product Service
Models
- BlazorEcommerce.Shared/Product.cs
- BlazorEcommerce.Shared/Category.cs
- BlazorEcommerce.Shared/ProductVariant.cs
-
JsonIgnore
means this property is excluded from Json Serialization. -
BlazorEcommerce.Shared/ProductVariant.cs
- BlazorEcommerce.Shared/ProductSearchResult.cs
Seeds
- BlazorEcommerce.Server/Data/DataContext.cs
Datebase
- Enter
dotnet ef migrations add Products
anddotnet ef update database
in CLI.
Service Responce with Generics
- BlazorEcommerce.Shared/ServiceResponse.cs
- On
T
every variable types can be posited.
Product Service in Server
Interface
- BlazorEcommerce.Server/Services/ProductService/IProductService.cs
Implement
- BlazorEcommerce.Server/Services/ProductService/ProductService.cs
-
Include
include overlapped data to return value. -
ThenInclude
is for multi level ofInclude
. -
Math.Ceiling
round up the value. -
Skip
skips over the first n elements in the sequence and returns a new sequence containing the remaining elements after the first n elements. -
Take
extracts the first n elements from the beginning of the target sequence and returns a new sequence containing only the elements taken.
Controller
- BlazorEcommerce.Server/Controllers/ProductController.cs
Dependency Injection
- BlazorEcommerce.Server/Program.cs
Product Service in Client
Interface
- BlazorEcommerce.Client/Services/ProductService/IProductService.cs
Interface
- BlazorEcommerce.Client/Services/ProductService/ProductService.cs
Dependency Injection
- BlazoreEcommerce.Client/Program.cs
Category
Category Service in Server
interface
- BlazoreEcommerce.Server/Services/CategoryService/ICategoryService.cs
Implement
- BlazoreEcommerce.Server/Services/CategoryService/CategoryService.cs
Controller
- BlazoreEcommerce.Server/Controllers/CategoryController.cs
Dependency Injection
- BlazorEcommerce.Server/Program.cs
Category Service in Client
Interface
- BlazorEcommerce.Client/Services/CategoryService/ICategoryService.cs
Implement
- BlazorEcommerce.Client/Services/CategoryService/CategoryService.cs
Dependency Injection
- BlazorEcommercs.Client/Program.cs
Cart
Local Storage
- To save cart data, you can use local storage in bkazor application.
Package in Client
- Download
Blazored.LocalStorage
.
Set
- BlazorEcommercs.Client/Program.cs
Models
- BlazorEcommerce.Shared/CartItem.cs
- BlazorEcommerce.Shared/CartProductResponse.cs
Cart Service in Server
Interface
- BlazorEcommerce.Server/Services/ICartService.cs
Implement
- BlazorEcommerce.Server/Services/CartService.cs
Dependency Injection
- BlazorEcommerce.Server/Program.cs
Cart Service in Client
Interface
- BlazorEcommerce.Client/Services/ICartService.cs
- BlazorEcommerce.Client/Services/CartService.cs
-
GetItemAsync
get data from local storage with key word. -
SetItemAsync
set data to local storage with key word. -
api/cart/products
is a post method in server. It will return data enveloped in Content.
Dependency Injection
- BlazorEcommerce.Client/Program.cs
View
Layout
Layout
- BlazorEcommerce.Client/Shared/ShopLayout.razor
- BlazorEcommerce.Client/Shared/ShopLayout.razor.cs
- BlazorEcommerce.Client/Shared/ShopLayout.razor.css
Set Layout in App
- BlazorEcommerce.Client/App.razor
Home
Home Button
- BlazorEcommerce.Client/Shared/HomeButton.razor
- BlazorEcommerce.Client/Shared/HomeButton.razor.cs
- BlazorEcommerce.Client/Shared/HomeButton.razor.css
Search
- BlazorEcommerce.Client/Shared/Search.razor
- BlazorEcommerce.Client/Shared/Search.razor.cs
Cart Counter
- BlazorEcommerce.Client/Shared/CartCounter.razor
- BlazorEcommerce.Client/Shared/CartCounter.razor.cs
-
IDisposable
implements to disubscreib the event.
Shop Nav Menu
- BlazorEcommerce.Client/Shared/ShopNavMenu.razor
- BlazorEcommerce.Client/Shared/ShopNavMenu.razor.cs
- BlazorEcommerce.Client/Shared/ShopNavMenu.razor.css
Body
- BlazorEcommerce.Client/Pages/Index.razor
- BlazorEcommerce.Client/Pages/Index.razor.cs
Products
Featured Products
- BlazorEcommerce.Client/Shared/FeaturedProducts.razor
- BlazorEcommerce.Client/Shared/FeaturedProducts.razor.cs
- BlazorEcommerce.Client/Shared/FeaturedProducts.razor.css
Product List
- BlazorEcommerce.Client/Shared/ProductList.razor
- BlazorEcommerce.Client/Shared/ProductList.razor.cs
- BlazorEcommerce.Client/Shared/ProductList.razor.css
Product Detail
- BlazorEcommerce.Client/Pages/ProductDetails.razor
- BlazorEcommerce.Client/Pages/ProductDetails.razor.cs
- BlazorEcommerce.Client/Pages/ProductDetails.razor.css
Cart
- BlazorEcommerce.Client/Pages/Cart.razor
- BlazorEcommerce.Client/Pages/Cart.razor.cs
- BlazorEcommerce.Client/Pages/Cart.razor.css
Show
Auth
Models
- BlazorEcommerce.Shared/User.cs
-
PasswordSalt
is added characters in your original password. - For example, your original password is yellow. But, you know, others also can use yellow for password. To avoid same passwords, we add salt like yellow#1Gn% or yellow9j?L.
-
So hashed
PasswordSalt
is powerful than normal securities. - BlazorEcommerce.Shared/UserRegister.cs
- BlazorEcommerce.Shared/UserLogin.cs
- BlazorEcommerce.Shared/UserLogin.cs
Set
- BlazorEcommerce.Server/Data/DataContext.cs
Datebase
- Enter
dotnet ef migrations add Users
anddotnet ef update database
in CLI.
Auth Service in Server
Package in Server
- Download
Microsoft.AspNetCore.Authentication.JwtBearer
.
Interface
- BlazorEcommerce.Server/Services/AuthService/IAuthService.cs
Implement
- BlazorEcommerce.Server/Services/AuthService/AuthService.cs
-
IConfiguration
reads appsettings.json. -
out
reference object address but the variable should be setted. -
ref
reference object address also, but the variable should have value before. -
out
andref
are useful when you have more than two return values. -
HMACSHA512
is a type of keyed hash algorithm that is constructed from the SHA-512 hash function and used as a Hash-based Message Authentication Code (HMAC). -
Claim
is a base of the common authorization approache and provides a way of sharing user information throughout the application in a consistent way. -
SymmetricSecurityKey
generates security key. -
SigningCredentials
specifies the signing key, signing key identifier, and security algorithms that are used by .NET to generate the digital signature for a SamlAssertion.
Controller
- BlazorEcommerce.Server/Controllers/AuthController.cs
Dependency Injection
- BlazorEcommerce.Server/Program.cs
Set
- BlazorEcommerce.Server/appsettings.json
Auth Service in Client
Interface
- BlazorEcommerce.Client/Services/AuthService/IAuthService.cs
Implement
- BlazorEcommerce.Client/Services/AuthService/AuthService.cs
Dependency Injection
- BlazorEcommerce.Client/Program.cs
Authorization
- For authorization, I will use Claim, JSON Web Token and Local Storage.
Package for Authorization
- Download
Microsoft.AspNetCore.Components.Authorization
andMicrosoft.AspNetCore.WebUtilities
in Client.
Auth State Provider
- BlazorEcommerce.Client/CustomAuthStateProvider.cs
-
AuthenticationStateProvider
class provides information about the authentication state of the current user. - We have to split jwt because of
HMACSHA512(base64UrlEncode(header) + "." + base64UrlEncode(payload))
. - Bearer authentication (also called token authentication) is an HTTP authentication scheme that involves security tokens called bearer tokens. The name “Bearer authentication” can be understood as “give access to the bearer of this token.” The bearer token is a cryptic string, usually generated by the server in response to a login request. The client must send this token in the Authorization header when making requests to protected resources
-
ClaimsPrincipal
means user andClaimsIdentity
means user information. So, we get user information from JWT first, and then create user with this user information. - And we will use
AuthorizeView
in our project, soAuthenticationState
andNotifyAuthenticationStateChanged
are for change authentication state.
Set
- BlazorEcommerce.Client/Program.cs
- BlazorEcommerce.Client/_imports.cs
View
Register
- BlazorEcommerce.Client/Pages/Register.razor
- BlazorEcommerce.Client/Pages/Register.razor.cs
Login
- BlazorEcommerce.Client/Pages/Login.razor
- BlazorEcommerce.Client/Pages/Login.razor.cs
- When you success the login, then you will return to
returnUrl
. QueryHelter is for this process.
Profile
- BlazorEcommerce.Client/Pages/Profile.razor
- BlazorEcommerce.Client/Pages/Profile.razor.cs
-
[Authorize]
means this page is for authorized user.
User Button
- BlazorEcommerce.Client/Shared/UserButton.razor
-
login?returnUrl=@NavigationManager.ToBaseRelativePath(NavigationManager.Uri)
means save current url to returnUrl variable in hyperlink url but go to login. -
BlazorEcommerce.Client/Shared/UserButton.razor.cs
- BlazorEcommerce.Client/Shared/UserButton.razor.css
- BlazorEcommerce.Client/App.razor
Run
User Button
Register
Login
- You can check your JSON Web Token in jwt.io.
Profile
Refactoring Auth Service
-
public int GetUserId() => int.Parse(_httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier));
returns UserId which is logged in now. - I will use it only in AuthService and use AuthService in other services.
Refactoring Auth Service in Server
Interface
- BlazorEcommerce.Server/Services/AuthService/IAuthService.cs
Implement
- BlazorEcommerce.Server/Services/AuthService/AuthService.cs
Set
- BlazorEcommerce.Server/Program.cs
Refactoring Auth Service in Client
Interface
- BlazorEcommerce.Client/Services/AuthService/IAuthService.cs
Implement
- BlazorEcommerce.Client/Services/AuthService/AuthService.cs
Cart with Authentication and Database
Models
-
To add authentication, add UserId in CartItem.
-
BlazorEcommerce.Shared/CartItem.cs
Set
- BlazorEcommerce.Server/Data/DataContext.cs
Database
- Type
dotnet ef migrations add CartItems
anddotnet ef database update
Cart Service in Server
Interface
- BlazorEcommerce.Server/Services/CartService/ICartService.cs
Implement
- BlazorEcommerce.Server/Services/CartService/CartService.cs
-
CountAsync
returns count of the list items.
Controller
- BlazorEcommerce.Server/Controllers/CartController.cs
Cart Service in Client
Interface
- BlazorEcommerce.Client/Services/CartService/ICartService.cs
Implement
- BlazorEcommerce.Client/Services/CartService/CartService.cs
Order
Models
- BlazorEcommerce.Shared/Order.cs
- BlazorEcommerce.Shared/OrderDetailsProductResponse.cs
- BlazorEcommerce.Shared/OrderDetailsResponse.cs
- BlazorEcommerce.Shared/OrderItem.cs
- BlazorEcommerce.Shared/OrderOverviewResponse.cs
Set
- BlazorEcommerce.Server/Data/DataContext.cs
Database
- Type
dotnet ef migrations add Orders
anddotnet ef database update
Order Service in Server
Interface
- BlazorEcommerce.Server/Services/OrderService/IOrderService.cs
Implement
- BlazorEcommerce.Server/Services/OrderService/OrderService.cs
Controller
- BlazorEcommerce.Server/Controllers/OrderController.cs
Set
- BlazorEcommerce.Server/Program.cs
Order Service in Client
Interface
- BlazorEcommerce.Client/Services/OrderService/IOrderService.cs
Implement
- BlazorEcommerce.Client/Services/OrderService/OrderService.cs
Set
- BlazorEcommerce.Client/Program.cs
View
Cart
- BlazorEcommerce.Client/Shared/UserButton.razor
- BlazorEcommerce.Client/Shared/UserButton.razor.cs
- BlazorEcommerce.Client/Shared/CartCounter.razor.cs
- BlazorEcommerce.Client/Pages/Login.razor.cs
- BlazorEcommerce.Client/Pages/Cart.razor.cs
Order
- BlazorEcommerce.Client/Pages/Cart.razor
- BlazorEcommerce.Client/Pages/Cart.razor.cs
- BlazorEcommerce.Client/Pages/Order.razor
- BlazorEcommerce.Client/Pages/Order.razor.cs
- BlazorEcommerce.Client/Pages/Order.razor.css
- BlazorEcommerce.Client/Pages/OrderDetails.razor
- BlazorEcommerce.Client/Pages/OrderDetails.razor.cs
- BlazorEcommerce.Client/Pages/OrderDetails.razor.css
Run
Cart
Order
Payment with Webhook
- A webhook in web development is a method of augmenting or altering the behavior of a web page or web application with custom callbacks.
Stripe
- It offers payment processing software and application programming interfaces (APIs) for e-commerce websites and mobile.
- Please read Stripe Documents, if you want to get more information.
Account
- Create account ot Stripe.
API Key
- Create your secret key from Stripe.
Stripe CLI
- Download Stripe-Cli.
- Login in Stripe with
stripe login
.
Package in Server
- Download
Stripe.net
in Server.
Payment Service in Server
Get User Email From Auth Service
- BlazorEcommerce.Server/Services/AuthService/IAuthService.cs
- BlazorEcommerce.Server/Services/AuthService/AuthService.cs
When you checkout, Get Cart Products from Database
- BlazorEcommerce.Server/Services/CartService/ICartService.cs
- BlazorEcommerce.Server/Services/CartService/CartService.cs
get Orders when you checkout
- BlazorEcommerce.Server/Services/OrderService/IOrderService.cs
- BlazorEcommerce.Server/Services/OrderService/OrderService.cs
- BlazorEcommerce.Server/Controllers/OrderController.cs
Payment Service
- BlazorEcommerce.Server/Services/PaymentService/IPaymentService.cs
- BlazorEcommerce.Server/Services/PaymentService/PaymentService.cs
- BlazorEcommerce.Server/Controllers/PaymentController.cs
Set
- BlazorEcommerce.Server/Program.cs
Refactoring Order Service in Client
- BlazorEcommerce.Client/Services/OrderService/IOrderService.cs
- BlazorEcommerce.Client/Services/OrderService/OrderService.cs
View
- BlazorEcommerce.Client/Pages/Cart.razor
- BlazorEcommerce.Client/Pages/Cart.razor.cs
- BlazorEcommerce.Client/Pages/OrderSuccess.razor
- BlazorEcommerce.Client/Pages/Cart.razor.cs
Run
Payment
Address
Models
- BlazorEcommerce.Shared/Address.cs
- BlazorEcommerce.Shared/User.cs
Set
- BlazorEcommerce.Shared/Program.cs
Database
- Type
dotnet ef migrations add UserAddress
anddotnet ef database update
.
Address Service in Server
Interface
- BlazorEcommerce.Server/Services/AddressService/IAddressService.cs
Implement
- BlazorEcommerce.Server/Services/AddressService/AddressService.cs
Controller
- BlazorEcommerce.Server/Controllers/AddressController.cs
Set
- BlazorEcommerce.Server/Program.cs
Address Service in Client
Interface
- BlazorEcommerce.Client/Services/AddressService/IAddressService.cs
Implement
- BlazorEcommerce.Client/Services/AddressService/AddressService.cs
Set
- BlazorEcommerce.Client/Program.cs
View
- BlazorEcommerce.Client/Shared/AddressForm.razor
- BlazorEcommerce.Client/Shared/AddressForm.razor.cs
- BlazorEcommerce.Client/Pages/Cart.razor
- BlazorEcommerce.Client/Pages/Cart.razor.cs
- BlazorEcommerce.Client/Pages/Profile.razor