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;

相关推荐
csdn_aspnet5 小时前
使用 ASP.NET Core 创建和下载 zip 文件
后端·asp.net·.netcore
csdn_aspnet5 小时前
在 ASP.NET Core 中压缩并减少图像的文件大小
后端·asp.net·.netcore
平凡君7 小时前
(七)消息队列-Kafka 序列化avro(传递)
分布式·kafka·linq
m0_748234717 小时前
Spring Boot 集成 Kafka
spring boot·kafka·linq
指尖下的技术7 小时前
Kafka面试题----如何保证Kafka消费者在消费过程中不丢失消息
分布式·kafka·linq
听我俩天13 小时前
ASP.NET 解决 NLog、log4net 和 Serilog 在 IIS 部署后不写日志的问题
后端·asp.net
m0_7482510814 小时前
使用 Qt 插件和 SQLCipher 实现 SQLite 数据库加密与解密
数据库·qt·sqlite
jay丿16 小时前
Django数据迁移
数据库·django·sqlite
qq_2979080118 小时前
asp.net运输公司车辆管理系统收入与费用统计软件车辆网上申请派车软件
sqlserver·开源·c#·asp.net