Asp.Net Web API| React.js| EF框架 | SQLite|

asp.net web api + EF + SQLite+React前端框架

设计一个首页面,包含三个按钮分别对应三类用户(数据查看,设计人员,管理员),当点击管理员的时候弹出一个前端页面可以输入信息(以学生数据为例),提交之后后端存储数据库。当点击数据查看的时候,能够看到管理员录入的所有的学生数据。


1. 后端部分 (ASP.NET Web API + EF + SQLite)

1.1 创建 ASP.NET Web API 项目
  1. 使用 Visual Studio 或 .NET CLI 创建一个新的 ASP.NET Web API 项目:

    bash 复制代码
    dotnet new webapi -n StudentManagementApi
    cd StudentManagementApi
  2. 安装必要的 NuGet 包:

    bash 复制代码
    dotnet add package Microsoft.EntityFrameworkCore
    dotnet add package Microsoft.EntityFrameworkCore.Sqlite
    dotnet add package Microsoft.EntityFrameworkCore.Tools
1.2 配置 SQLite 数据库和 EF Core
  1. appsettings.json 中配置 SQLite 连接字符串:

    json 复制代码
    {
      "ConnectionStrings": {
        "DefaultConnection": "Data Source=students.db"
      }
    }
  2. 创建 Student 实体类:

    csharp 复制代码
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Major { get; set; }
    }
  3. 创建 ApplicationDbContext

csharp 复制代码
   // 定义数据库上下文类,用于与数据库交互
public class ApplicationDbContext : DbContext
{
    public DbSet<Student> Students { get; set; } // 表示 Students 表

    // 添加一个接受 DbContextOptions 的构造函数
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options) // 将选项传递给基类
    {
    }
    // 如果需要,可以保留无参构造函数(仅用于手动配置)
    public ApplicationDbContext()
    {
    }
}
  1. 添加迁移并更新数据库:

    bash 复制代码
    dotnet ef migrations add InitialCreate
    dotnet ef database update
1.3 创建 API 控制器
  1. 创建 StudentsController
csharp 复制代码
// 定义一个 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 应用
  1. 使用 Create React App 创建前端项目:

    bash 复制代码
    npx create-react-app student-management-frontend
    cd student-management-frontend
  2. 安装 Axios 用于 HTTP 请求:

    bash 复制代码
    npm install axios
2.2 设计首页
  1. 编辑 App.js 文件:
javascript 复制代码
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 启动后端

在后端项目目录下运行:

bash 复制代码
dotnet run

API 将在 http://localhost:5000 上运行。

运行成功后,弹出swagger UI页面,测试API接口是否正常;

3.2 启动前端

在前端项目目录下运行:

bash 复制代码
npm start

React 应用将在 http://localhost:3000 上运行。


4. 功能测试

  1. 点击"管理员"按钮,填写学生信息并提交。
  2. 点击"数据查看"按钮,查看管理员录入的学生数据。
  3. 确保数据能够正确存储到 SQLite 数据库中,并从前端显示出来。

5. 结果展示

前端页面:


美化页面

过程中又遇到前端页面乱码的问题,这是因为使用visual stdio 创建的js文本中的中文字符存储的格式问题导致的,具体解决方法是使用记事本打开有中文字符的文档,然后另存为,把其中的编码改成UTF-8即可。

1. 在src目录下创建style.css 样式文件
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 样式文件,并对按钮进行一些基本的样式设置:

javascript 复制代码
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>
                    {/* 姓名输入框 */}
                    <input
                        type="text"
                        placeholder="姓名"
                        value={formData.name}
                        onChange={(e) => setFormData({ ...formData, name: e.target.value })} // 更新表单数据
                        className="form-input"
                    />
                    {/* 年龄输入框 */}
                    <input
                        type="number"
                        placeholder="年龄"
                        value={formData.age}
                        onChange={(e) => setFormData({ ...formData, age: e.target.value })}
                        className="form-input"
                    />
                    {/* 专业输入框 */}
                    <input
                        type="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;

相关推荐
Muyuan199811 小时前
25.Paper RAG Agent 优化记录:上传反馈、计算器安全与 Chunk 参数调整
python·安全·django·sqlite·fastapi
星辰_mya3 天前
分布式系统里的“快递中转站”——消息队列(MQ)
c#·linq
code_pgf6 天前
sqlite数据库cmakelist.txt编译
数据库·sqlite
_F_y6 天前
SQLite3的基础使用
jvm·数据库·sqlite
刘~浪地球6 天前
日志平台架构设计
c#·linq
IntMainJhy6 天前
【flutter for open harmony】第三方库 Flutter 二维码生成的鸿蒙化适配与实战指南
数据库·flutter·华为·sqlite·harmonyos
IntMainJhy7 天前
【flutter for open harmony】第三方库Flutter 国际化多语言的鸿蒙化适配与实战指南
数据库·flutter·华为·sqlite·harmonyos
医疗信息化王工7 天前
基于ASP.NET Core的医院不良事件管理系统的架构设计
后端·asp.net
IntMainJhy7 天前
【flutter for open harmony】Flutter SQLite 本地数据库的鸿蒙化适配与实战指南
数据库·flutter·sqlite
北冥有羽Victoria8 天前
Django Auth组件完整版教程:从原理到项目落地
大数据·服务器·数据库·后端·python·django·sqlite