服务器部署测试~~~

This commit is contained in:
heiye111
2025-10-10 16:02:38 +08:00
parent 8ab52738c0
commit 5c186aa446
87 changed files with 5062 additions and 167 deletions

581
HTML/idexe.html Normal file
View File

@@ -0,0 +1,581 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ASP.NET Core Minimal API CRUD Test</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f4f4f4;
color: #333;
}
h1, h2, h3 {
color: #0056b3;
}
.container {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.entity-section {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
padding: 20px;
flex: 1;
min-width: 450px;
box-sizing: border-box;
}
.operation-section {
padding: 15px;
border: 1px solid #eee;
border-radius: 5px;
margin-bottom: 15px;
background-color: #f9f9f9;
}
.operation-section h4 {
margin-top: 0;
color: #333;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input[type="text"],
input[type="number"],
input[type="email"],
input[type="password"],
input[type="checkbox"],
textarea {
width: calc(100% - 22px);
padding: 8px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
input[type="checkbox"] {
width: auto;
margin-right: 5px;
}
button {
background-color: #007bff;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.2s ease;
margin-right: 10px;
}
button:hover {
background-color: #0056b3;
}
.result-box {
background-color: #e9ecef;
border: 1px solid #ced4da;
padding: 15px;
margin-top: 15px;
border-radius: 5px;
white-space: pre-wrap;
font-family: monospace;
max-height: 300px;
overflow-y: auto;
}
.error {
color: red;
font-weight: bold;
}
.success {
color: green;
font-weight: bold;
}
.loading {
color: gray;
font-style: italic;
}
ul {
list-style-type: none;
padding: 0;
}
li {
background-color: #f0f0f0;
margin-bottom: 5px;
padding: 8px;
border-radius: 3px;
border-left: 5px solid #007bff;
}
</style>
</head>
<body>
<h1>ASP.NET Core Minimal API CRUD 测试</h1>
<p>确保您的 ASP.NET Core 应用正在运行,并监听以下基准 URL。</</p>
<div class="container">
<!-- Todo Section -->
<div class="entity-section">
<h2>待办事项 (Todos) CRUD</h2>
<!-- 获取所有 Todo -->
<div class="operation-section">
<h4>获取所有待办事项</h4>
<button onclick="getAllTodos()">获取所有 Todo</button>
<div id="allTodosResult" class="result-box"></div>
</div>
<!-- 根据 ID 获取 Todo -->
<div class="operation-section">
<h4>根据 ID 获取待办事项</h4>
<label for="getTodoId">待办事项 ID:</label>
<input type="number" id="getTodoId" value="1">
<button onclick="getTodoById()">获取 Todo</button>
<div id="singleTodoResult" class="result-box"></div>
</div>
<!-- 创建 Todo -->
<div class="operation-section">
<h4>创建待办事项</h4>
<label for="createTodoTitle">标题:</label>
<input type="text" id="createTodoTitle" placeholder="新的待办事项标题">
<label for="createTodoIsCompleted">已完成:</label>
<input type="checkbox" id="createTodoIsCompleted">
<label for="createTodoUserId">用户ID (关联的用户):</label>
<input type="number" id="createTodoUserId" value="1" placeholder="例如: 1">
<button onclick="createTodo()">创建 Todo</button>
<div id="createTodoResult" class="result-box"></div>
</div>
<!-- 更新 Todo -->
<div class="operation-section">
<h4>更新待办事项</h4>
<label for="updateTodoId">待办事项 ID:</label>
<input type="number" id="updateTodoId" value="1">
<label for="updateTodoTitle">新标题:</label>
<input type="text" id="updateTodoTitle" placeholder="更新后的待办事项标题">
<label for="updateTodoIsCompleted">已完成:</label>
<input type="checkbox" id="updateTodoIsCompleted">
<label for="updateTodoUserId">用户ID (关联的用户):</label>
<input type="number" id="updateTodoUserId" value="1" placeholder="例如: 1">
<button onclick="updateTodo()">更新 Todo</button>
<div id="updateTodoResult" class="result-box"></div>
</div>
<!-- 删除 Todo -->
<div class="operation-section">
<h4>删除待办事项</h4>
<label for="deleteTodoId">待办事项 ID:</label>
<input type="number" id="deleteTodoId" value="1">
<button onclick="deleteTodo()">删除 Todo</button>
<div id="deleteTodoResult" class="result-box"></div>
</div>
</div>
<!-- User Section -->
<div class="entity-section">
<h2>用户 (Users) CRUD</h2>
<!-- 获取所有 User -->
<div class="operation-section">
<h4>获取所有用户</h4>
<button onclick="getAllUsers()">获取所有 User</button>
<div id="allUsersResult" class="result-box"></div>
</div>
<!-- 根据 ID 获取 User -->
<div class="operation-section">
<h4>根据 ID 获取用户</h4>
<label for="getUserId">用户 ID:</label>
<input type="number" id="getUserId" value="1">
<button onclick="getUserById()">获取 User</button>
<div id="singleUserResult" class="result-box"></div>
</div>
<!-- 用户验证/登录 (使用 PATCH 方法) -->
<div class="operation-section">
<h4>用户验证 (Check User Credentials)</h4>
<label for="verifyUsername">用户名:</label>
<input type="text" id="verifyUsername" placeholder="要验证的用户名">
<label for="verifyPasswordHash">密码哈希:</label>
<input type="password" id="verifyPasswordHash" placeholder="对应用户的密码哈希">
<button onclick="verifyUserCredentials()">验证用户</button>
<div id="verifyUserResult" class="result-box"></div>
</div>
<!-- 创建 User -->
<div class="operation-section">
<h4>创建用户</h4>
<label for="createUsername">用户名:</label>
<input type="text" id="createUsername" placeholder="新用户名">
<label for="createUserEmail">邮箱:</label>
<input type="email" id="createUserEmail" placeholder="user@example.com">
<label for="createUserPasswordHash">密码哈希 (例如: plainTextPassword的哈希值):</label>
<input type="password" id="createUserPasswordHash" placeholder="PasswordHash">
<button onclick="createUser()">创建 User</button>
<div id="createUserResult" class="result-box"></div>
</div>
<!-- 更新 User -->
<div class="operation-section">
<h4>更新用户</h4>
<label for="updateUserId">用户 ID:</label>
<input type="number" id="updateUserId" value="1">
<label for="updateUsername">新用户名:</label>
<input type="text" id="updateUsername" placeholder="更新后的用户名">
<label for="updateUserEmail">新邮箱:</label>
<input type="email" id="updateUserEmail" placeholder="updated@example.com">
<label for="updateUserPasswordHash">新密码哈希:</label>
<input type="password" id="updateUserPasswordHash" placeholder="UpdatedPasswordHash">
<button onclick="updateUser()">更新 User</button>
<div id="updateUserResult" class="result-box"></div>
</div>
<!-- 删除 User -->
<div class="operation-section">
<h4>删除用户</h4>
<label for="deleteUserId">用户 ID:</label>
<input type="number" id="deleteUserId" value="1">
<button onclick="deleteUser()">删除 User</button>
<div id="deleteUserResult" class="result-box"></div>
</div>
</div>
</div>
<script>
// === 配置您的 API 基础 URL ===
// 如果您的 API 运行在其他端口或地址,请修改此变量
const BASE_URL = 'http://localhost:5071';
// 对于 HTTPS可能需要改为 'https://localhost:5001'
// === 辅助函数 ===
async function fetchData(url, method = 'GET', data = null) {
const options = {
method: method,
headers: {
'Content-Type': 'application/json',
},
};
if (data) {
options.body = JSON.stringify(data);
}
try {
const response = await fetch(url, options);
let result;
// 尝试解析JSON响应但对于204 No Content等情况可能没有响应体
if (response.headers.get("content-type")?.includes("application/json")) {
result = await response.json();
} else {
result = await response.text(); // 如果不是 JSON尝试获取文本
}
if (!response.ok) {
throw new Error(`HTTP 错误! Status: ${response.status}, Message: ${result}`);
}
return result;
} catch (error) {
console.error('Fetch error:', error);
throw error;
}
}
function displayResult(elementId, data, isError = false) {
const resultBox = document.getElementById(elementId);
resultBox.innerHTML = '';
if (isError) {
resultBox.classList.add('error');
resultBox.textContent = `Error: ${data}`;
} else {
resultBox.classList.remove('error');
resultBox.classList.add('success');
if (typeof data === 'object') {
resultBox.textContent = JSON.stringify(data, null, 2);
} else {
resultBox.textContent = data;
}
}
resultBox.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
// === Todo Functions ===
async function getAllTodos() {
const resultBox = document.getElementById('allTodosResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '加载中...';
try {
const todos = await fetchData(`${BASE_URL}/todos`);
displayResult('allTodosResult', todos);
} catch (error) {
displayResult('allTodosResult', error.message, true);
}
}
async function getTodoById() {
const id = document.getElementById('getTodoId').value;
if (!id) {
displayResult('singleTodoResult', '请输入待办事项 ID。', true);
return;
}
const resultBox = document.getElementById('singleTodoResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '加载中...';
try {
const todo = await fetchData(`${BASE_URL}/todos/${id}`);
displayResult('singleTodoResult', todo);
} catch (error) {
displayResult('singleTodoResult', error.message, true);
}
}
async function createTodo() {
const title = document.getElementById('createTodoTitle').value;
const isCompleted = document.getElementById('createTodoIsCompleted').checked;
const userId = parseInt(document.getElementById('createTodoUserId').value);
if (!title) {
displayResult('createTodoResult', '标题不能为空。', true);
return;
}
if (isNaN(userId)) {
displayResult('createTodoResult', '用户ID必须是数字。', true);
return;
}
const newTodo = {
title: title,
isCompleted: isCompleted,
userId: userId
};
const resultBox = document.getElementById('createTodoResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '创建中...';
try {
const createdTodo = await fetchData(`${BASE_URL}/todos`, 'POST', newTodo);
displayResult('createTodoResult', createdTodo);
// 刷新所有 Todo 列表
getAllTodos();
} catch (error) {
displayResult('createTodoResult', error.message, true);
}
}
async function updateTodo() {
const id = document.getElementById('updateTodoId').value;
const title = document.getElementById('updateTodoTitle').value;
const isCompleted = document.getElementById('updateTodoIsCompleted').checked;
const userId = parseInt(document.getElementById('updateTodoUserId').value);
if (!id) {
displayResult('updateTodoResult', '请输入待办事项 ID。', true);
return;
}
if (!title) {
displayResult('updateTodoResult', '标题不能为空。', true);
return;
}
if (isNaN(userId)) {
displayResult('updateTodoResult', '用户ID必须是数字。', true);
return;
}
const updatedTodo = {
id: parseInt(id), // ID 也需要包含在 PUT 请求体中
title: title,
isCompleted: isCompleted,
userId: userId
};
const resultBox = document.getElementById('updateTodoResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '更新中...';
try {
await fetchData(`${BASE_URL}/todos/${id}`, 'PUT', updatedTodo);
displayResult('updateTodoResult', `待办事项 (ID: ${id}) 更新成功。`);
getTodoById(); // 刷新单个Todo
getAllTodos(); // 刷新所有Todo
} catch (error) {
displayResult('updateTodoResult', error.message, true);
}
}
async function deleteTodo() {
const id = document.getElementById('deleteTodoId').value;
if (!id) {
displayResult('deleteTodoResult', '请输入待办事项 ID。', true);
return;
}
const resultBox = document.getElementById('deleteTodoResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '删除中...';
try {
const response = await fetchData(`${BASE_URL}/todos/${id}`, 'DELETE');
displayResult('deleteTodoResult', response);
getAllTodos(); // 刷新所有Todo
} catch (error) {
displayResult('deleteTodoResult', error.message, true);
}
}
// === User Functions ===
async function getAllUsers() {
const resultBox = document.getElementById('allUsersResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '加载中...';
try {
const users = await fetchData(`${BASE_URL}/users`);
displayResult('allUsersResult', users);
} catch (error) {
displayResult('allUsersResult', error.message, true);
}
}
async function getUserById() {
const id = document.getElementById('getUserId').value;
if (!id) {
displayResult('singleUserResult', '请输入用户 ID。', true);
return;
}
const resultBox = document.getElementById('singleUserResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '加载中...';
try {
const user = await fetchData(`${BASE_URL}/users/${id}`);
displayResult('singleUserResult', user);
} catch (error) {
displayResult('singleUserResult', error.message, true);
}
}
async function createUser() {
const username = document.getElementById('createUsername').value;
const email = document.getElementById('createUserEmail').value;
const passwordHash = document.getElementById('createUserPasswordHash').value;
if (!username || !email || !passwordHash) {
displayResult('createUserResult', '用户名、邮箱和密码哈希不能为空。', true);
return;
}
const newUser = {
username: username,
email: email,
passwordHash: passwordHash
};
const resultBox = document.getElementById('createUserResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '创建中...';
try {
const createdUser = await fetchData(`${BASE_URL}/users`, 'POST', newUser);
displayResult('createUserResult', createdUser);
getAllUsers(); // 刷新所有用户列表
} catch (error) {
displayResult('createUserResult', error.message, true);
}
}
// PACTH /users - 验证用户凭据
async function verifyUserCredentials() {
const username = document.getElementById('verifyUsername').value;
const passwordHash = document.getElementById('verifyPasswordHash').value;
if (!username || !passwordHash) {
displayResult('verifyUserResult', '用户名和密码哈希不能为空。', true);
return;
}
const userToVerify = {
// PATCH 请求体中通常不包含 ID因为您的 API 是通过 Username 来查找
// 但如果需要,也可以写上 Id: 0 或其他占位符
username: username,
passwordHash: passwordHash
};
const resultBox = document.getElementById('verifyUserResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '验证中...';
try {
// 使用 PATCH 方法发送请求
const response = await fetchData(`${BASE_URL}/users`, 'PATCH', userToVerify);
displayResult('verifyUserResult', response);
} catch (error) {
// 如果 API 返回的是 BadRequest (400)fetchData 会抛出异常
// 异常的 message 应该包含 API 返回的错误信息
displayResult('verifyUserResult', error.message, true);
}
}
async function updateUser() {
const id = document.getElementById('updateUserId').value;
const username = document.getElementById('updateUsername').value;
const email = document.getElementById('updateUserEmail').value;
const passwordHash = document.getElementById('updateUserPasswordHash').value;
if (!id) {
displayResult('updateUserResult', '请输入用户 ID。', true);
return;
}
if (!username || !email || !passwordHash) {
displayResult('updateUserResult', '用户名、邮箱和密码哈希不能为空。', true);
return;
}
const updatedUser = {
id: parseInt(id), // ID 也需要包含在 PUT 请求体中
username: username,
email: email,
passwordHash: passwordHash
};
const resultBox = document.getElementById('updateUserResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '更新中...';
try {
await fetchData(`${BASE_URL}/users/${id}`, 'PUT', updatedUser);
displayResult('updateUserResult', `用户 (ID: ${id}) 更新成功。`);
getUserById(); // 刷新单个用户
getAllUsers(); // 刷新所有用户
} catch (error) {
displayResult('updateUserResult', error.message, true);
}
}
async function deleteUser() {
const id = document.getElementById('deleteUserId').value;
if (!id) {
displayResult('deleteUserResult', '请输入用户 ID。', true);
return;
}
const resultBox = document.getElementById('deleteUserResult');
resultBox.classList.remove('success', 'error');
resultBox.classList.add('loading');
resultBox.textContent = '删除中...';
try {
const response = await fetchData(`${BASE_URL}/users/${id}`, 'DELETE');
displayResult('deleteUserResult', response);
getAllUsers(); // 刷新所有用户列表
} catch (error) {
displayResult('deleteUserResult', error.message, true);
}
}
// 页面加载完成后自动获取所有待办事项和用户
document.addEventListener('DOMContentLoaded', () => {
getAllTodos();
getAllUsers();
});
</script>
</body>
</html>