asp.net web api + EF + SQLite+React前端框架
設計一個首頁面,包含三個按鈕分別對應三類用戶(數據查看,設計人員,管理員),當點擊管理員的時候彈出一個前端頁面可以輸入信息(以學生數據為例),提交之后后端存儲數據庫。當點擊數據查看的時候,能夠看到管理員錄入的所有的學生數據。
1. 后端部分 (ASP.NET Web API + EF + SQLite)
1.1 創建 ASP.NET Web API 項目
-
使用 Visual Studio 或 .NET CLI 創建一個新的 ASP.NET Web API 項目:
dotnet new webapi -n StudentManagementApi cd StudentManagementApi
-
安裝必要的 NuGet 包:
dotnet add package Microsoft.EntityFrameworkCore dotnet add package Microsoft.EntityFrameworkCore.Sqlite dotnet add package Microsoft.EntityFrameworkCore.Tools
1.2 配置 SQLite 數據庫和 EF Core
-
在
appsettings.json
中配置 SQLite 連接字符串:{"ConnectionStrings": {"DefaultConnection": "Data Source=students.db"} }
-
創建
Student
實體類:public class Student {public int Id { get; set; }public string Name { get; set; }public int Age { get; set; }public string Major { get; set; } }
-
創建
ApplicationDbContext
:
// 定義數據庫上下文類,用于與數據庫交互
public class ApplicationDbContext : DbContext
{public DbSet<Student> Students { get; set; } // 表示 Students 表// 添加一個接受 DbContextOptions 的構造函數public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options) // 將選項傳遞給基類{}// 如果需要,可以保留無參構造函數(僅用于手動配置)public ApplicationDbContext(){}
}
- 添加遷移并更新數據庫:
dotnet ef migrations add InitialCreate dotnet ef database update
1.3 創建 API 控制器
- 創建
StudentsController
:
// 定義一個 API 控制器,處理學生數據的增刪改查
[Route("api/[controller]")] // 定義路由前綴為 api/students
[ApiController]
public class StudentsController : ControllerBase
{private readonly ApplicationDbContext _context; // 注入數據庫上下文// 構造函數注入public StudentsController(ApplicationDbContext context){_context = context;}// GET: api/students - 獲取所有學生數據[HttpGet]public async Task<ActionResult<IEnumerable<Student>>> GetStudents(){return await _context.Students.ToListAsync(); // 查詢并返回所有學生數據}// POST: api/students - 添加新學生數據[HttpPost]public async Task<ActionResult<Student>> PostStudent(Student student){_context.Students.Add(student); // 將新學生數據添加到數據庫await _context.SaveChangesAsync(); // 保存更改return CreatedAtAction(nameof(GetStudents), new { id = student.Id }, student); // 返回創建的資源}}
2. 前端部分 (React)
2.1 創建 React 應用
-
使用 Create React App 創建前端項目:
npx create-react-app student-management-frontend cd student-management-frontend
-
安裝 Axios 用于 HTTP 請求:
npm install axios
2.2 設計首頁
- 編輯
App.js
文件:
import logo from './logo.svg';
import './App.css';
import React, { useState } from 'react';
import axios from 'axios';function App() {// 定義狀態變量,控制是否顯示管理員表單const [showAdminForm, setShowAdminForm] = useState(false);// 定義狀態變量,存儲從后端獲取的學生數據const [students, setStudents] = useState([]);// 點擊 "Admin" 按鈕時,顯示管理員表單const handleAdminClick = () => {setShowAdminForm(true);};// 點擊 "Data Viewer" 按鈕時,從后端獲取所有學生數據const handleViewDataClick = async () => {try {// 發送 GET 請求到后端 API 獲取學生數據(要注意一致和后端的api一致)const response = await axios.get('https://localhost:5000/api/students');// 更新狀態變量,存儲獲取到的學生數據setStudents(response.data);} catch (error) {console.error('Error fetching students:', error);}};// 提交管理員表單時,將學生數據發送到后端const handleSubmit = async (event) => {event.preventDefault(); // 阻止表單默認提交行為// 獲取表單輸入值const name = event.target.name.value;const age = event.target.age.value;const major = event.target.major.value;try {// 發送 POST 請求到后端 API 添加學生數據await axios.post('https://localhost:5000/api/students', { name, age, major });alert('Student added successfully!'); // 提示用戶操作成功setShowAdminForm(false); // 隱藏表單} catch (error) {console.error('Error adding student:', error);}};return (<div>{/* 頁面標題 */}<h1>Welcome to Student Management System</h1>{/* 功能按鈕 */}<button onClick={handleAdminClick}>Admin</button><button onClick={handleViewDataClick}>Data Viewer</button><button>Designer</button>{/* 管理員表單 */}{showAdminForm && (<form onSubmit={handleSubmit}><h2>Add Student</h2>{/* 輸入學生姓名 */}<input type="text" name="name" placeholder="Name" required />{/* 輸入學生年齡 */}<input type="number" name="age" placeholder="Age" required />{/* 輸入學生專業 */}<input type="text" name="major" placeholder="Major" required />{/* 提交按鈕 */}<button type="submit">Submit</button></form>)}{/* 顯示學生數據 */}{students.length > 0 && (<div><h2>Student List</h2><ul>{/* 遍歷學生數據并顯示 */}{students.map((student) => (<li key={student.id}>{student.name} - {student.age} years old - {student.major}</li>))}</ul></div>)}</div>);
}export default App;
3. 運行項目
3.1 啟動后端
在后端項目目錄下運行:
dotnet run
API 將在 http://localhost:5000
上運行。
運行成功后,彈出swagger UI頁面,測試API接口是否正常;
3.2 啟動前端
在前端項目目錄下運行:
npm start
React 應用將在 http://localhost:3000
上運行。
4. 功能測試
- 點擊“管理員”按鈕,填寫學生信息并提交。
- 點擊“數據查看”按鈕,查看管理員錄入的學生數據。
- 確保數據能夠正確存儲到 SQLite 數據庫中,并從前端顯示出來。
5. 結果展示
前端頁面:
美化頁面
過程中又遇到前端頁面亂碼的問題,這是因為使用visual stdio 創建的js文本中的中文字符存儲的格式問題導致的,具體解決方法是使用記事本打開有中文字符的文檔,然后另存為,把其中的編碼改成UTF-8即可。
1. 在src目錄下創建style.css 樣式文件
/* styles.css */
body {font-family: Arial, sans-serif; /* 設置字體 */background-color: #f4f4f4; /* 設置背景顏色 */display: flex; /* 使用 Flexbox 布局 */justify-content: center; /* 水平居中 */align-items: center; /* 垂直居中 */height: 100vh; /* 設置高度為視口高度 */margin: 0; /* 移除默認外邊距 */
}.app-container {text-align: center; /* 文本居中 */background-color: white; /* 設置容器背景顏色 */padding: 20px; /* 設置內邊距 */border-radius: 8px; /* 設置圓角 */box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* 添加陰影效果 */
}.btn {display: block; /* 將按鈕設置為塊級元素 */width: 200px; /* 設置按鈕寬度 */margin: 10px auto; /* 設置外邊距并水平居中 */padding: 10px; /* 設置內邊距 */color: white; /* 設置文本顏色 */border: none; /* 移除邊框 */border-radius: 4px; /* 設置圓角 */cursor: pointer; /* 設置鼠標指針樣式 */font-size: 16px; /* 設置字體大小 */transition: background-color 0.3s ease; /* 添加過渡效果 */
}.btn-green {background-color: #4CAF50; /* 設置綠色按鈕背景顏色 */
}.btn-green:hover {background-color: #45a049; /* 設置鼠標懸停時的背景顏色 */
}.btn-gray {background-color: #808080; /* 設置灰色按鈕背景顏色 */
}.btn-gray:hover {background-color: #666666; /* 設置鼠標懸停時的背景顏色 */
}.admin-form {margin-top: 20px; /* 設置表單頂部外邊距 */text-align: left; /* 表單內容左對齊 */
}.form-input {display: block; /* 將輸入框設置為塊級元素 */width: 100%; /* 設置輸入框寬度為父元素寬度 */margin-bottom: 10px; /* 設置底部外邊距 */padding: 8px; /* 設置內邊距 */border: 1px solid #ccc; /* 設置邊框 */border-radius: 4px; /* 設置圓角 */
}.student-list ul {list-style-type: none; /* 移除列表樣式 */padding: 0; /* 移除默認內邊距 */
}.student-item {background-color: #f9f9f9; /* 設置列表項背景顏色 */margin: 5px 0; /* 設置上下外邊距 */padding: 10px; /* 設置內邊距 */border-radius: 4px; /* 設置圓角 */box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 添加陰影效果 */
}
2. 修改 App.js
在 App.js 中引入 CSS 樣式文件,并對按鈕進行一些基本的樣式設置:
import React, { useState } from 'react'; // 導入 React 和 useState 鉤子
import axios from 'axios'; // 導入 Axios 用于發送 HTTP 請求
import './styles.css'; // 引入 CSS 樣式文件function App() {const [showAdminForm, setShowAdminForm] = useState(false); // 控制管理員表單的顯示狀態const [students, setStudents] = useState([]); // 存儲學生數據const [formData, setFormData] = useState({name: '', // 學生姓名age: '', // 學生年齡major: '' // 學生專業});// 獲取所有學生數據const fetchStudents = async () => {try {const response = await axios.get('http://localhost:5000/api/students'); // 發送 GET 請求獲取學生數據setStudents(response.data); // 更新學生數據狀態} catch (error) {console.error('獲取學生數據失敗:', error); // 捕獲并打印錯誤信息}};// 提交學生數據const handleSubmit = async (e) => {e.preventDefault(); // 阻止表單默認提交行為try {await axios.post('http://localhost:5000/api/students', formData); // 發送 POST 請求添加新學生數據setShowAdminForm(false); // 關閉管理員表單fetchStudents(); // 刷新學生數據} catch (error) {console.error('提交學生數據失敗:', error); // 捕獲并打印錯誤信息}};return (<div className="app-container">{/* 頁面標題 */}<h1>學生管理系統</h1>{/* 操作按鈕 */}<button className="btn btn-green" onClick={fetchStudents}>數據查看</button> {/* 點擊后獲取學生數據 */}<button className="btn btn-green" onClick={() => setShowAdminForm(true)}>設計人員</button> {/* 顯示設計人員表單 */}<button className="btn btn-gray" onClick={() => setShowAdminForm(true)}>管理員</button> {/* 顯示管理員表單 */}{/* 管理員表單 */}{showAdminForm && (<form onSubmit={handleSubmit} className="admin-form"><h2>錄入學生信息</h2>{/* 姓名輸入框 */}<inputtype="text"placeholder="姓名"value={formData.name}onChange={(e) => setFormData({ ...formData, name: e.target.value })} // 更新表單數據className="form-input"/>{/* 年齡輸入框 */}<inputtype="number"placeholder="年齡"value={formData.age}onChange={(e) => setFormData({ ...formData, age: e.target.value })}className="form-input"/>{/* 專業輸入框 */}<inputtype="text"placeholder="專業"value={formData.major}onChange={(e) => setFormData({ ...formData, major: e.target.value })}className="form-input"/>{/* 提交按鈕 */}<button type="submit" className="btn btn-green">提交</button></form>)}{/* 數據展示 */}<div className="student-list"><h2>學生列表</h2><ul>{students.map((student) => (<li key={student.id} className="student-item">{/* 顯示學生信息 */}{student.name} - {student.age}歲 - {student.major}</li>))}</ul></div></div>);
}export default App;
效果如下圖所示:
控制臺報錯:獲取數據失敗,404,大概率是因為App.js中的api路徑寫錯了。注意要和后端一致。
可以在Swagger UI中查看確認Request URL;