接續上一篇
在Startup.cs中啟用靜態資源
於專案新增目錄命名為wwwroot(會自動變成地球的圖示)
對wwwroot去進行
引入bs4跟jquery3.6
測試Client端有UI時的互動存取(透過jQuery)
接著要實作
產品分類資料查詢與增加
新增PCategoryController.cs和對應的新增Action及查詢Action
~\Controllers\PCategoryController.cs
同步形式的API存取
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Net5EFCoreWebApiApp.Data;
using Net5EFCoreWebApiApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Net5EFCoreWebApiApp.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PCategoryController : ControllerBase
{
//Startup.cs中註冊EF服務後,就可在特定控制器藉由.net core預設DI,透過建構子去實踐存取ProductDbContext。
private readonly ProductDbContext _dbContext;
public PCategoryController(ProductDbContext dbContext)
{
_dbContext = dbContext;
}
[HttpPost("Add")]
public ActionResult<int> AddProductCategory(PCategory pCategory)
{
if (pCategory == null)
return NotFound();
if (string.IsNullOrEmpty(pCategory.CTitle))
return NotFound();
pCategory.CId = Guid.NewGuid();
_dbContext.PCategories.Add(pCategory);
int RowCount = _dbContext.SaveChanges();
return CreatedAtAction(nameof(AddProductCategory),RowCount);
}
[HttpGet("Show")]
public ActionResult<List<PCategory>> ShowProductCategory()
{
var categories = _dbContext.PCategories.ToList();
return categories;
}
}
}
透過.net core DI我們在建構子注入DbContext就能在整個Controller程式中進行存取異動
新增對應靜態資源頁面
~\wwwroot\PCategory\Add.html
<!DOCTYPE html>
<html>
<head>
<title>Add ProductType</title>
<link href="../css/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<script src="../js/jquery/jquery.min.js"></script>
</head>
<body>
<div style="padding:20px;border:1px solid #0094ff;width:600px;margin:30px;">
<h3>產品類別</h3>
<hr />
<div class="form-horizontal">
<div class="form-group col-4">
<label>產品類別</label>
<input type="text" class="form-control" id="CategoryTitle">
</div>
<div class="form-group">
<div class="col-md-2 col-md-10">
<button type="submit" id="btnSubmit" class="btn btn-primary">Submit</button>
</div>
<div>
<span id="msg" class="danger"></span>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$('#btnSubmit').click(function () {
$.ajax({
type: 'post',
url: "/api/pcategory/add",
dataType: "text",
data: JSON.stringify({
CTitle: $('#CategoryTitle').val()
}),
contentType: 'application/json',
success: function (result) {
if (result == "1") {
$('#msg').text('成功添加');
}
}
});
});
</script>
</body>
</html>
~\wwwroot\PCategory\Show.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link href="../css/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<script src="../js/jquery/jquery.min.js"></script>
</head>
<body style="margin:20px;">
<table id="tbProductCategory" class="table table-bordered">
<thead>
<tr>
<td>產品類別ID</td>
<td>產品類別名稱</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script type="text/javascript">
$(function () {
var tbody = $('#tbProductCategory tbody');
$.ajax({
type: 'get',
url: '/api/pcategory/show',
dataType: 'json',
success: function (result) {
$.each(result, function (n, value) {
var tr_val = "";
tr_val += "<tr><td>" + value.cId
+ "</td><td>" + value.cTitle
+ "</td></tr>";
tbody += tr_val;
});
$('#tbProductCategory').append(tbody);
}
});
});
</script>
</body>
</html>
運行效果
而在過去用ado.net搭配寫法或者上述寫法
基本上都是採用同步的API存取方式
所以基本上單位時間內能處理消化的請求量或稱為「吞吐(流通)量Throughput」有限
因此會有阻塞問題
由於EFCore有支援異步存取的相關API(方法名Async後綴)
這裡可以再改為非同步的API存取
非同步(異步)形式的API存取
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Net5EFCoreWebApiApp.Data;
using Net5EFCoreWebApiApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Net5EFCoreWebApiApp.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PCategoryController : ControllerBase
{
//Startup.cs中註冊EF服務後,就可在特定控制器藉由.net core預設DI,透過建構子去實踐存取ProductDbContext。
private readonly ProductDbContext _dbContext;
public PCategoryController(ProductDbContext dbContext)
{
_dbContext = dbContext;
}
[HttpPost("Add")]
public async Task<ActionResult<int>> AddProductCategory(PCategory pCategory)
{
if (pCategory == null)
return NotFound();
if (string.IsNullOrEmpty(pCategory.CTitle))
return NotFound();
pCategory.CId = Guid.NewGuid();
_dbContext.PCategories.Add(pCategory);
int RowCount = await _dbContext.SaveChangesAsync();
return CreatedAtAction(nameof(AddProductCategory),RowCount);
}
[HttpGet("Show")]
public async Task<ActionResult<List<PCategory>>> ShowProductCategory()
{
var categories = await _dbContext.PCategories.ToListAsync();
return categories;
}
}
}
Ref:
The Ultimate Guide to Async and Await in C# and ASP.NET
https://exceptionnotfound.net/async-await-in-asp-net-csharp-ultimate-guide/
[效能調教] 使用 Async / Await 非同步機制加快 Web API 回應時間
https://dotblogs.com.tw/wasichris/2017/06/08/101137#%E7%B5%90%E8%AB%96
網站測試工具-JMeter教學
https://www.astralweb.com.tw/website-test-tool-jmeter-teaching/
JMeter-網頁壓力測試教學
https://www.astralweb.com.tw/jmeter-website-stress-testing-tutorial/
.NET Web应用中为什么要使用async/await异步编程
https://www.cnblogs.com/xhznl/p/13064731.html
為什麼需要使用非同步程式設計,真的可以提升整體應用程式的執行效能嗎?
https://csharpkh.blogspot.com/2019/07/Asynchronous-ThreadPool-programming-synchronous-NET-Core-Framework-async-await.html
ASP.NET async 基本心法
https://blog.darkthread.net/blog/async-aspnet/
本篇已同步發表至個人部落格
https://coolmandiary.blogspot.com/2022/01/net-core-web-api24apiefcorepart2api.html