我想让员工使用用户名和密码进行注册和登录(1:1 关系)。但 Swagger UI 中有一些错误,参数检查照片以获取更多信息:
代码没有错误,我多次尝试更改AuthController.cs,但还是一样。
还有其他课程,但我认为这些课程与此问题相关。
型号 员工.cs
using System;
using System.ComponentModel.DataAnnotations;
public class Employee
{
public int Id { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
[RegularExpression(@"^\+222\d{7}$")]
public string? PhoneNumber { get; set; }
public string? Department { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public bool IsDeleted { get; set; }
public User User { get; set; }
}
用户.cs
using System.ComponentModel.DataAnnotations;
public class User
{
public int Id { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
public Employee Employee { get; set; }
}
DBcontext.cs
using Microsoft.EntityFrameworkCore;
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> options) : base(options) { }
public DbSet<User> Users { get; set; }
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOne(u => u.Employee)
.WithOne(e => e.User)
.HasForeignKey<Employee>(e => e.Id);
base.OnModelCreating(modelBuilder);
}
}
Authcontroller.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using EmployeeAPI.Models;
namespace EmployeeAPI.Controllers
{
[Route("api/auth")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly IConfiguration _configuration;
private readonly DataContext _context;
public AuthController(DataContext context, IConfiguration configuration)
{
_context = context;
_configuration = configuration;
}
// User registration
[HttpPost("register")]
public async Task<IActionResult> Register([FromBody] User userRegistration)
{
if (await _context.Users.AnyAsync(u => u.Username == userRegistration.Username))
{
return BadRequest("Username is already taken.");
}
var user = new User
{
Username = userRegistration.Username,
Password = PasswordHash.HashPassword(userRegistration.Password)
};
_context.Users.Add(user);
await _context.SaveChangesAsync();
return Ok("User registered successfully.");
}
// User login
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] User userLogin)
{
var user = await _context.Users.SingleOrDefaultAsync(u => u.Username == userLogin.Username);
if (user == null || !PasswordHash.VerifyPassword(userLogin.Password, user.Password))
{
return BadRequest("Invalid username or password.");
}
var token = GenerateJwtToken(user);
return Ok(new { Token = token });
}
private string GenerateJwtToken(User user)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.Username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken(
_configuration["Jwt:Issuer"],
_configuration["Jwt:Issuer"],
claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
}
员工.cs
using EmployeeAPI.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace EmployeeAPI.Controllers
{
[Authorize]
[Route("api/employees")]
[ApiController]
public class EmployeeController : ControllerBase
{
private readonly DataContext _context;
public EmployeeController(DataContext context)
{
_context = context;
}
// GET: api/employees
[HttpGet]
public async Task<ActionResult<PagedResult<Employee>>> GetEmployees(int page = 1, int pageSize = 10, string department = null)
{
var username = User.Identity.Name;
var query = _context.Employees.AsQueryable();
if (!string.IsNullOrEmpty(department))
{
query = query.Where(e => e.Department == department);
}
query = query.Where(e => e.User.Username == username);
var totalItems = await query.CountAsync();
var employees = await query.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync();
return new PagedResult<Employee>
{
Page = page,
PageSize = pageSize,
TotalItems = totalItems,
Data = employees
};
}
// Soft delete an employee
[HttpDelete("{id}")]
public async Task<IActionResult> SoftDeleteEmployee(int id)
{
var username = User.Identity.Name;
var employee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == id && e.User.Username == username);
if (employee == null)
{
return NotFound();
}
employee.IsDeleted = true;
employee.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
return NoContent();
}
// Update an employee
[HttpPut("{id}")]
public async Task<IActionResult> UpdateEmployee(int id, Employee updatedEmployee)
{
var username = User.Identity.Name;
var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == id && e.User.Username == username);
if (existingEmployee == null)
{
return NotFound();
}
// Update the properties you want to change
existingEmployee.FirstName = updatedEmployee.FirstName;
existingEmployee.LastName = updatedEmployee.LastName;
existingEmployee.PhoneNumber = updatedEmployee.PhoneNumber;
existingEmployee.Department = updatedEmployee.Department;
existingEmployee.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
return NoContent();
}
}
}
如果您解释属性下面的红线,它是您平台的拼写检查器,可以忽略。
您的代码是正确的,如果您的代码运行没有任何错误,请不要注意红线并继续。
您应该尝试将请求模型和实体模型分开。同样,要返回响应数据,请使用 DTO。
public class RegisterUserRequest
{
public string Username { get; set; } = null!;
public string Password { get; set; } = null!;
public string? FirstName { get; set; }
public string? LastName { get; set; }
[RegularExpression(@"^\+222\d{7}$")]
public string? PhoneNumber { get; set; }
public string? Department { get; set; }
}
[HttpPost("register")]
public async Task<IActionResult> Register([FromBody] RegisterUserRequest registerUserRequest)
{
if (await _context.Users.AnyAsync(u => u.Username == registerUserRequest.Username))
{
return BadRequest("Username is already taken.");
}
var user = new User
{
Username = registerUserRequest.Username,
Password = PasswordHash.HashPassword(registerUserRequest.Password)
};
var employee = new Employee
{
FirstName = registerUserRequest.FirstName,
LastName = registerUserRequest.LastName,
PhoneNumber = registerUserRequest.PhoneNumber,
Department = registerUserRequest.Department,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow,
IsDeleted = false,
User = user
};
_context.Users.Add(user);
_context.Employees.Add(employee);
await _context.SaveChangesAsync();
return Ok("User registered successfully.");
}
您不应在 API 请求中获取以下属性。
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public bool IsDeleted { get; set; }