TOC
Asp .Net Core 3.x
Asp .Net Core
本质是 一个Server
+ 多个中间件(Middleware)组成的管道(Pipline)
。
本身是一个console application
,经 Main() > CreateHostBuilder(args).Build()
后成为web application
。
Asp .Net Core 应用多样性
- MVC:/Home/Index
- Razor Pages: /SomePage
- SignalR: /Hub/Chat
4. Blazor
基于Component的编程模型,Blazor宿主模型:
- 客户端宿主模型:
- Mono解释器:
- 开源的.NET Freamework
- 可以解释IL(中间语言)
- 代码的IL是包含在.NET的Assembly里
- 浏览器可以执行mono,(webAssembly)
- mono将Assembly的代码解析为WebAssembly
- Mono解释器:
- 服务端宿主模型
Create Project
- New > Project > Asp .Net core web application
Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
Create Models, Service and Register services
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<IDepartmentService, DepartmentService>();
services.AddSingleton<IEmployeeService, EmpolyeeService>();
}
Config配置信息源
-
appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "BlazorAppDemo": { "BoldDepartmentEmployeeC: 30 } }
Startup.cs 注入Config,映射为options类
private readonly IConfiguration configuration;
public Startup(IConfiguration configuration)
{
this.configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSingleton<IDepartmentService, DepartmentService>();
services.AddSingleton<IEmployeeService, EmpolyeeService>();
services.Configure<BlazorAppDemoOptions>(configuration.GetSection("BlazorAppDemo"));
}
Using libman Install bootstrap
Add > Client-Side Library > bootstrap@4.4.1 > Install, libman.json
{
"version": "1.0",
"defaultProvider": "unpkg",
"libraries": [
{
"library": "bootstrap@4.4.1",
"destination": "wwwroot/lib/bootstrap/",
"files": [
"dist/css/bootstrap.css"
]
}
]
}
Using BuildBundlerMinifier Merge and Minify css files
-
Add > New Item, bundleconfig.json
[ { "outputFileName": "wwwroot/css/all.min.css", "inputFiles": [ "wwwroot/css/site.css", "wwwroot/lib/bootstrap/dist/css/bootstrap.css" ] }, { "outputFileName": "wwwroot/css/bootstrap.css", "inputFiles": [ "wwwroot/lib/bootstrap/dist/css/bootstrap.css" ], "minify": {"enabled": true} } ]
-
Manage NuGet packges > BuildBundlerMinifier
ASPNETCORE_ENVIRONMENT
-
\Properties\launchSettings.json
{ "profiles": { "BlazorAppDemo": { "commandName": "Project", "launchBrowser": true, "applicationUrl": "https://localhost:5001;http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
Views
-
Pages > _Host.cshtml: Add > NewItem > Razor View
@page "/" @namespace BlazorAppDemo.Pages @addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Blazore App Demo</title> <base href="~/" /> <link rel="stylesheet" href="css/bootstrap.css" /> <link rel="stylesheet" href="css/site.css" /> </head> <body> <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app> <script src="_framework/blazor.server.js"></script> </body> </html>
-
App.razor: Add > NewItem > Razor Component
<Router AppAssembly="@typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> <NotFound> <LayoutView Layout="@typeof(MainLayout)"> <p>Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router>
-
_Imports.razor : Add > NewItem > Razor Component
@using System.Net.Http @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.JSInterop @using BlazorAppDemo.Models @using BlazorAppDemo.Services
-
Shared > MainLayout.razor: Add > NewItem > Razor Component
@inherits LayoutComponentBase <div class="container"> <div class="row"> <div class="col-md-2"> <img asp-append-version="true" alt="logo" src="/images/Home.png" style="height: 60px; width: 100px;" /> </div> <div class="col-md-10"> <span class="h2">Blazor App Demo</span> </div> </div> <div class="row"> <div class="col-md-12"> @Body </div> </div> </div>
-
_Imports.razor
@using BlazorAppDemo.Shared
-
-
Pages > Index.razor: Add > NewItem > Razor Component
@page "/" @inject IDepartmentService departmentService @if (departments == null) { <p><em>loading...</em></p> } else { <div class="row"> <div class="col-md-10 offset-md-2"> <table class="table"> <tr> <th>Name</th> <th>Location</th> <th>EmployeeCount</th> <th>Opration</th> </tr> @foreach (var item in departments) { <DepartmentItem department="@item"></DepartmentItem> } </table> </div> </div> <div class="row"> <div class="col-md-4"> <a href="/add-department">Add</a> </div> </div> } @code { IEnumerable<Department> departments; protected override async Task OnInitializedAsync() { departments = await departmentService.GetAll(); } }
-
Componets > DepartmentItem.razor: Add > NewItem > Razor Component
@using Microsoft.Extensions.Options @inject IOptions<BlazorAppDemoOptions> options <tr> @if (Department.EmployeeCount > options.Value.BoldDepartmentEmployeeCount) { <td><strong>@Department.Name</strong></td> } else { <td>@Department.Name</td> } <td>@Department.Location</td> <td>@Department.EmployeeCount</td> </tr> @code { [Parameter] public Department Department { get; set; } }
-
_Imports.razor
@using BlazorAppDemo.Components
-
-
Pages > Department > AddDepartment.razor: Add > NewItem > Razor Component
@page "/add-department" @inject IDepartmentService departmentService @inject NavigationManager navigationManager <EditForm Model="@department" OnValidSubmit="@HandleValidSubmit"> <DataAnnotationsValidator /> <ValidationSummary /> <div class="row form-group"> <div class="col-md-2 offset-md-2"> <label for="name">Name</label> </div> <div class="col-md-6"> <InputText id="name" class="form-control" @bind-Value="@department.Name" /> </div> </div> <div class="row form-group"> <div class="col-md-2 offset-md-2"> <label for="location">Location</label> </div> <div class="col-md-6"> <InputText id="location" class="form-control" @bind-Value="@department.Location" /> </div> </div> <div class="row form-group"> <div class="col-md-2 offset-md-2"> <label for="employeeCount">EmployeeCount</label> </div> <div class="col-md-6"> <InputText id="employeeCount" class="form-control" @bind-Value="@employeeCount" /> </div> </div> <div class="row"> <div class="col-md-2 offset-md-2"> <button type="submit" class="btn btn-primary">Add</button> </div> </div> </EditForm> @code { private Department department = new Department(); private string employeeCount; private async Task HandleValidSubmit() { department.EmployeeCount = int.Parse(employeeCount); await departmentService.Add(department); navigationManager.NavigateTo("/"); } }
项目地址
github: https://github.com/leezhuang96/Asp.NetCoreDemo
「下次一定」
下次一定
使用微信扫描二维码完成支付