自动映射实体和模型

This commit is contained in:
hello 2024-04-04 08:35:01 +08:00
parent 5516bb80dd
commit 055cf5997f
5 changed files with 79 additions and 64 deletions

View File

@ -0,0 +1,17 @@
using AutoMapper;
using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.Models.Users;
using Microsoft.Extensions.Options;
namespace HelloShop.IdentityService.AutoMapper;
public class UsersMapConfiguration : Profile
{
public UsersMapConfiguration()
{
CreateMap<UserCreateRequest, User>();
CreateMap<UserUpdateRequest, User>();
CreateMap<User, UserDetailsResponse>();
CreateMap<User, UserListItem>();
}
}

View File

@ -1,4 +1,5 @@
using HelloShop.IdentityService.Entities; using AutoMapper;
using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks; using HelloShop.IdentityService.EntityFrameworks;
using HelloShop.IdentityService.Models.Users; using HelloShop.IdentityService.Models.Users;
using HelloShop.ServiceDefaults.Authorization; using HelloShop.ServiceDefaults.Authorization;
@ -14,24 +15,15 @@ namespace HelloShop.IdentityService.Controllers
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]
public class UsersController(IdentityServiceDbContext dbContext) : ControllerBase public class UsersController(IdentityServiceDbContext dbContext, IMapper mapper) : ControllerBase
{ {
[HttpGet] [HttpGet]
[Authorize(IdentityPermissions.Users.Default)] [Authorize(IdentityPermissions.Users.Default)]
public async Task<ActionResult<PagedResponse<UserListItem>>> GetUsers([FromQuery] UserListRequest model) public async Task<ActionResult<PagedResponse<UserListItem>>> GetUsers([FromQuery] UserListRequest model)
{ {
var userList= await dbContext.Set<User>().Skip((model.PageNumber - 1) * model.PageSize).Take(model.PageSize).ToListAsync(); var userList = await dbContext.Set<User>().Skip((model.PageNumber - 1) * model.PageSize).Take(model.PageSize).ToListAsync();
var result = userList.Select(e => new UserListItem var result = mapper.Map<IReadOnlyList<UserListItem>>(userList);
{
Id = e.Id,
UserName = e.UserName!,
PhoneNumber = e.PhoneNumber,
PhoneNumberConfirmed = e.PhoneNumberConfirmed,
Email = e.Email,
EmailConfirmed = e.EmailConfirmed,
CreationTime = e.CreationTime,
}).ToList();
var responseModel = new PagedResponse<UserListItem>(result, result.Count); var responseModel = new PagedResponse<UserListItem>(result, result.Count);
@ -51,51 +43,26 @@ namespace HelloShop.IdentityService.Controllers
return Forbid(); return Forbid();
} }
User? user = dbContext.Set<User>().Find(id); User? user = await dbContext.Set<User>().FindAsync(id);
if (user == null) if (user == null)
{ {
return NotFound(); return NotFound();
} }
UserDetailsResponse responseModel = new() return mapper.Map<UserDetailsResponse>(user);
{
Id = user.Id,
UserName = user.UserName!,
PhoneNumber = user.PhoneNumber,
PhoneNumberConfirmed = user.PhoneNumberConfirmed,
Email = user.Email,
EmailConfirmed = user.EmailConfirmed,
CreationTime = user.CreationTime,
};
return Ok(responseModel);
} }
[HttpPost] [HttpPost]
[Authorize(IdentityPermissions.Users.Create)] [Authorize(IdentityPermissions.Users.Create)]
public async Task<ActionResult<UserDetailsResponse>> PostUser([FromBody] UserCreateRequest model) public async Task<ActionResult<UserDetailsResponse>> PostUser([FromBody] UserCreateRequest model)
{ {
var user = new User var user = mapper.Map<User>(model);
{
UserName = model.UserName,
PhoneNumber = model.PhoneNumber,
Email = model.Email
};
await dbContext.AddAsync(user); await dbContext.AddAsync(user);
await dbContext.SaveChangesAsync(); await dbContext.SaveChangesAsync();
UserDetailsResponse responseModel = new() var responseModel = mapper.Map<UserDetailsResponse>(user);
{
Id = user.Id,
UserName = user.UserName,
PhoneNumber = user.PhoneNumber,
PhoneNumberConfirmed = user.PhoneNumberConfirmed,
Email = user.Email,
EmailConfirmed = user.EmailConfirmed,
CreationTime = user.CreationTime,
};
return CreatedAtAction(nameof(GetUser), new { id = user.Id }, responseModel); return CreatedAtAction(nameof(GetUser), new { id = user.Id }, responseModel);
} }
@ -107,44 +74,57 @@ namespace HelloShop.IdentityService.Controllers
{ {
if (model.Id != id) if (model.Id != id)
{ {
throw new ArgumentException("Id mismatch", nameof(model)); return BadRequest();
} }
var user = dbContext.Set<User>().Find(id); var user = mapper.Map<User>(model);
if (user != null) DbSet<User> users = dbContext.Set<User>();
users.Entry(user).State = EntityState.Modified;
try
{ {
user.UserName = model.UserName; await dbContext.SaveChangesAsync();
user.PhoneNumber = model.PhoneNumber; }
user.Email = model.Email; catch (DbUpdateConcurrencyException)
{
if (!users.Any(e => e.Id == id))
{
return NotFound();
}
else
{
throw;
}
} }
await dbContext.SaveChangesAsync(); return NoContent();
return Ok();
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]
[Authorize(IdentityPermissions.Users.Delete)] [Authorize(IdentityPermissions.Users.Delete)]
public async Task<IActionResult> DeleteUser(int id, [FromServices] IAuthorizationService authorizationService) public async Task<IActionResult> DeleteUser(int id, [FromServices] IAuthorizationService authorizationService)
{ {
var user = dbContext.Set<User>().Find(id); var user = await dbContext.Set<User>().FindAsync(id);
if (user != null) if (user is null)
{ {
var result = await authorizationService.AuthorizeAsync(User, user, IdentityPermissions.Users.Delete); return NotFound();
if (result.Succeeded)
{
dbContext.Remove(user);
dbContext.SaveChanges();
return Ok();
}
} }
return Unauthorized(); var authorizationResult = await authorizationService.AuthorizeAsync(User, user, IdentityPermissions.Users.Delete);
if (authorizationResult.Succeeded)
{
dbContext.Remove(user);
await dbContext.SaveChangesAsync();
return NoContent();
}
return Forbid();
} }
[HttpDelete] [HttpDelete]

View File

@ -57,6 +57,7 @@ builder.Services.AddDataSeedingProviders();
builder.Services.AddOpenApi(); builder.Services.AddOpenApi();
builder.Services.AddPermissionDefinitions(); builder.Services.AddPermissionDefinitions();
builder.Services.AddAuthorization().AddDistributedMemoryCache().AddHttpClient().AddHttpContextAccessor().AddTransient<IPermissionChecker, LocalPermissionChecker>().AddCustomAuthorization(); builder.Services.AddAuthorization().AddDistributedMemoryCache().AddHttpClient().AddHttpContextAccessor().AddTransient<IPermissionChecker, LocalPermissionChecker>().AddCustomAuthorization();
builder.Services.AddModelMapper();
var app = builder.Build(); var app = builder.Build();

View File

@ -0,0 +1,16 @@
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
namespace HelloShop.ServiceDefaults.Extensions;
public static class ModelBindingExtensionns
{
public static IServiceCollection AddModelMapper(this IServiceCollection services, Assembly? assembly = null)
{
assembly ??= Assembly.GetCallingAssembly();
services.AddAutoMapper(assembly);
return services;
}
}

View File

@ -8,6 +8,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" /> <FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.0.0-preview.1.24108.1" /> <PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.0.0-preview.1.24108.1" />
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="9.0.0-preview.1.24113.3" /> <PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="9.0.0-preview.1.24113.3" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.7.0" /> <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.7.0" />