Asp.Net Core學習筆記:入門篇
阿新 • • 發佈:2020-11-06
# Asp.Net Core 學習
基於.Net Core 2.2版本的學習筆記。
## 常識
像Django那樣自動檢查程式碼更新,自動過載伺服器(太方便了)
```
dotnet watch run
```
## 託管設定
設定專案檔案的`AspNetCoreHostingModel`屬性。
```xml
netcoreapp2.2
InProcess
```
- InProcess:使用IIS伺服器託管
- OutOfProcess:使用自帶Kestrel伺服器託管
## 中介軟體入門
- 可同時被訪問和請求
- 可以處理請求後,將請求傳遞給下一個中介軟體
- 可以處理請求後,使管道短路
- 可以傳出響應
- 中介軟體是按照新增順序執行的
通過在`Configure`中新增引數`ILogger logger`引入Asp.Net Core自帶的日誌元件。
```c#
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILogger logger)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.Use(async (context, next) =>
{
context.Response.ContentType = "text/plain;charset=utf-8";
//await context.Response.WriteAsync("Hello!");
logger.LogDebug("M1: 傳入請求");
await next();
logger.LogDebug("M1: 傳出響應");
});
app.Use(async (context, next) =>
{
context.Response.ContentType = "text/plain;charset=utf-8";
logger.LogDebug("M2: 傳入請求");
await next();
logger.LogDebug("M2: 傳出響應");
});
app.Run(async (context) =>
{
//await context.Response.WriteAsync("你好!");
await context.Response.WriteAsync("M3: 處理請求,生成響應");
logger.LogDebug("M3: 處理請求,生成響應");
});
}
```
輸出日誌:(可以看到三個中介軟體的執行過程)
```
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/2.0 GET https://localhost:44383/
StudyManagement.Startup:Debug: M1: 傳入請求
StudyManagement.Startup:Debug: M2: 傳入請求
StudyManagement.Startup:Debug: M3: 處理請求,生成響應
StudyManagement.Startup:Debug: M2: 傳出響應
StudyManagement.Startup:Debug: M1: 傳出響應
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 52.8954ms 200 text/plain;charset=utf-8
StudyManagement.Startup:Debug: M1: 傳入請求
StudyManagement.Startup:Debug: M2: 傳入請求
StudyManagement.Startup:Debug: M3: 處理請求,生成響應
StudyManagement.Startup:Debug: M2: 傳出響應
StudyManagement.Startup:Debug: M1: 傳出響應
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 34.3387ms 200 text/plain;charset=utf-8
```
## 靜態檔案支援
所有靜態檔案都在目錄`wwwroot`下
### 首先
```c#
// 設定預設檔案
// 不設定的話,預設就是index.html/default.html這幾個
var defaultFileOpinions = new DefaultFilesOptions();
defaultFileOpinions.DefaultFileNames.Clear();
defaultFileOpinions.DefaultFileNames.Add("test.html");
// 新增預設檔案中介軟體,必須在UseStaticFiles之前註冊
app.UseDefaultFiles(defaultFileOpinions);
// 新增靜態檔案中介軟體
app.UseStaticFiles();
```
### DirectoryBrowser 中介軟體
可以在瀏覽器瀏覽 `wwwroot` 下的內容。不推薦在生產環境中使用。
```c#
app.UseDirectoryBrowser();
```
### FileServer 中介軟體
集成了`UseDefaultFiles`, `UseStaticFiles`, `UseDirectoryBrowser`三個中介軟體的功能。同樣不推薦在生產環境中使用。
```c#
var fileServerOpinions = new FileServerOptions();
fileServerOpinions.DefaultFilesOptions.DefaultFileNames.Clear();
fileServerOpinions.DefaultFilesOptions.DefaultFileNames.Add("test.html");
app.UseFileServer(fileServerOpinions);
```
## 開發者異常頁面
```c#
if (env.IsDevelopment())
{
var developerExceptionPageOptions = new DeveloperExceptionPageOptions();
// 顯示程式碼行數
developerExceptionPageOptions.SourceCodeLineCount = 10;
app.UseDeveloperExceptionPage();
}
app.Run(async (context) =>
{
throw new Exception("自己丟擲的異常");
});
```
## 開發環境變數
- Development:開發環境
- Staging:演示(模擬、臨時)環境
- Production:正式(生產)環境
Ops:
- 使用`ASPNETCORE_ENVIRONMENT`環境變數設定開發環境。
- 在開發機上,在`launchSettings.json`檔案中設定環境變數。
- 在Staging和Production環境時,儘量在作業系統設定環境變數。
- 使用`IHostEnvironment`服務訪問執行時環境
- 除了標準環境之外還支援自定義環境(UAT、QA等)
## 引入MVC框架
### 首先新增MVC服務。
```c#
public void ConfigureServices(IServiceCollection services)
{
// 單純引入核心MVC服務,只有核心功能
services.AddMvcCore();
// 一般用這個,功能多
services.AddMvc();
}
```
### 新增中介軟體
```c#
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILogger logger)
{
if (env.IsDevelopment())
{
var developerExceptionPageOptions = new DeveloperExceptionPageOptions();
// 顯示程式碼行數
developerExceptionPageOptions.SourceCodeLineCount = 10;
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
```
MVC路由規則:`/控制器名稱/方法名稱`,(不區分大小寫)
例如下面例子的路由是:`/home/index`
### HomeController程式碼:
```c#
public class HomeController : Controller
{
public string Index()
{
return "home controller";
}
}
```
## 初步瞭解模型和依賴注入
### 定義模型
```c#
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string ClassName { get; set; }
public string Email { get; set; }
}
```
### 定義介面
```c#
public interface IStudentRepository
{
Student GetById(int id);
void Save(Student student);
}
```
### 實現介面
目前還沒接入資料庫,定義一個假資料的類
```c#
public class MockStudentRepository : IStudentRepository
{
private List _students;
public MockStudentRepository()
{
_students = new List
{
new Student { Id=1, Name="小米", ClassName="紅米", Email="[email protected]" },
new Student { Id=2, Name="華為", ClassName="榮耀", Email="[email protected]" },
new Student { Id=3, Name="oppo", ClassName="vivo", Email="[email protected]" },
};
}
public Student GetById(int id)
{
return _students.FirstOrDefault(a => a.Id == id);
}
public void Save(Student student) => throw new NotImplementedException();
}
```
### 註冊依賴注入
Asp.Net Core依賴注入容器註冊服務有三種
- AddSingleton
- AddTransient
- AddScoped
依賴注入的優點
- 低耦合
- 高測試性,更加方便進行單元測試
```c#
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// 註冊依賴注入,將實現類與介面繫結
services.AddSingleton();
}
```
### 在模型中使用依賴注入
```c#
public class StudentController : Controller
{
private readonly IStudentRepository _studentRepository;
// 通過建構函式注入的方式注入 IStudentRepository
public StudentController(IStudentRepository studentRepository)
{
_studentRepository = studentRepository;
}
public JsonResult Index(int id)
{
return Json(_studentRepository.GetById(id));
}
}
```
## 控制器入門
### 內容格式協商
在控制器方法中使用 `ObjectResult` 返回型別,支援內容協商,根據請求頭引數返回資料,
```c#
// 支援內容格式協商
public ObjectResult Details(int id)
{
return new ObjectResult(_studentRepository.GetById(id));
}
```
如:
```
Accept: application/xml
```
將返回xml格式。注:還要新增xml序列化器。
```c#
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
// 註冊XML序列化器
.AddXmlSerializerFormatters();
}
```
## 檢視入門
### 將資料從控制器傳遞到檢視的方法
前兩種都是弱型別的
- ViewData
- ViewBag
- 強型別檢視
### ViewData
- 弱型別字典物件
- 使用string型別的鍵值,儲存和chaxun
- 執行時動態解析
- 沒有智慧感知,編譯時也沒有型別檢查
使用方法:
```c#
ViewData["Title"] = "學生檢視";
ViewData["Model"] = model;
```
cshtml程式碼:
```scss
姓名:@ViewBag.Student.Name
班級:@ViewBag.Student.ClassName
```
### 強型別檢視
在控制器中傳給View()模型
```c#
public IActionResult GetView()
{
var model = _studentRepository.GetById(1);
return View(model);
}
```
在cshtml中指定模型型別
```scss
@model StudyManagement.Models.Student
```
## 佈局檢視 LayoutView
### 建立佈局檢視
```scss
@ViewBag.Title
@RenderBody()
@RenderSection("Scripts", required: false)
```
### 渲染檢視
```scss
@model IEnumerable
@{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "首頁 學生列表";
}
```
### 檢視節點 Section
在佈局視圖裡渲染節點
```scss
@RenderSection("Scripts", required: false)
```
在普通視圖裡定義節點
```scss
@section Scripts{
}
```
### 檢視開始 ViewStart
我的理解就是`_ViewStart.cshtml`檔案所在目錄下的每個檢視檔案開始渲染先執行這個檔案的內容。一般直接放在`Views`目錄下,全域性生效,可以放在各個子資料夾下,這樣可以覆蓋全域性的`_ViewStart.cshtml`。
```scss
@{
Layout = "_Layout";
}
```
### 檢視匯入 ViewImports
用來匯入名稱空間、註冊模型等等n多種操作。
生效機制和ViewStart差不多。
## 路由
- 常規路由(傳統路由)
- 屬性路由
### 常規路由
在`MapRoute`方法中傳入就好了。
```c#
// 自定義路由
app.UseMvc(route =>route.MapRoute("default",
"{controller=Home}/{action=Index}/{id?}"));
```
### 屬性路由
比傳統路由更加靈活,可以搭配傳統路由使用。
即在控制器方法上新增路由註解,一個方法可以同時對映多個路由。
```c#
[Route("Home/Index")]
public IActionResult Index()
{
return View(_studentRepository.GetAll());
}
```
路由中也可以指定引數
```c#
[Route("test/{id?}")]
public IActionResult Details(int id = 1)
{
var model = _studentRepository.GetById(id);
var viewModel = new StudentDetailsViewModel
{
Student = model,
PageTitle = "viewmodel裡的頁面標題"
};
return View(viewModel);
}
```
可以直接在控制器類上加註解,`[controller]/[action]`。
## 歡迎交流
交流問題請在微信公眾號後臺留言,每一條資訊我都會回覆哈~
- 微信公眾號:畫星星高手
- 打程式碼直播間:[https://live.bilibili.com/11883038](https://live.bilibili.com/11883038)
- 知乎:[https://www.zhihu.com/people/dealiaxy](https://www.zhihu.com/people/dealiaxy)
- 專欄:[https://zhuanlan.zhihu.com/deali](https://zhuanlan.zhihu.co
@ViewData["Title"]
@{ var student = ViewData["model"] as StudyManagement.Models.Student; } 姓名:@student.Name 班級:@student.ClassName ``` ### ViewBag ```c# // 直接給動態屬性賦值 ViewBag.PageTitle = "ViewBag標題"; ViewBag.Student = model; ``` cshtml使用: ```html@ViewBag.PageTitle
強型別模型
- @Model.Id
- @Model.Name
- @Model.ClassName
- @Model.Email
強型別模型
@Model.PageTitle
- @Model.Student.Id
- @Model.Student.Name
- @Model.Student.ClassName
- @Model.Student.Email
Id | 姓名 | 班級 | 郵箱 |
@student.Id | @student.Name | @student.ClassName | @student.Email |