I'm using the ASP.NET Boilerplate framework to do a small project and I used Swagger UI Integration to check the API within the project. I noticed that the Get
and GetAll
are still using POST method while the others are in their respective HTTP verb for example Create
is POST, Edit
is UPDATE, etc... I read the documentation and tried what they suggested in this [Documentation]
(https://aspnetboilerplate.com/Pages/Documents/Dynamic-Web-API#http-verbs)
Edit 1: Code for UserAppServiceClass
[AbpAuthorize(PermissionNames.Pages_Users)]
public class UserAppService : AsyncCrudAppService<User, UserDto, long, PagedResultRequestDto, CreateUserDto, UpdateUserDto>, IUserAppService
{
private readonly UserManager _userManager;
private readonly RoleManager _roleManager;
private readonly IRepository<Role> _roleRepository;
public UserAppService(
IRepository<User, long> repository,
UserManager userManager,
IRepository<Role> roleRepository,
RoleManager roleManager)
: base(repository)
{
_userManager = userManager;
_roleRepository = roleRepository;
_roleManager = roleManager;
}
[HttpGet]
public override async Task<UserDto> Get(EntityDto<long> input)
{
var user = await base.Get(input);
var userRoles = await _userManager.GetRolesAsync(user.Id);
user.Roles = userRoles.Select(ur => ur).ToArray();
return user;
}
[HttpPost]
public override async Task<UserDto> Create(CreateUserDto input)
{
CheckCreatePermission();
var user = ObjectMapper.Map<User>(input);
user.TenantId = AbpSession.TenantId;
user.Password = new PasswordHasher().HashPassword(input.Password);
user.IsEmailConfirmed = true;
//Assign roles
user.Roles = new Collection<UserRole>();
foreach (var roleName in input.RoleNames)
{
var role = await _roleManager.GetRoleByNameAsync(roleName);
user.Roles.Add(new UserRole(AbpSession.TenantId, user.Id, role.Id));
}
CheckErrors(await _userManager.CreateAsync(user));
return MapToEntityDto(user);
}
[HttpPut]
public override async Task<UserDto> Update(UpdateUserDto input)
{
CheckUpdatePermission();
var user = await _userManager.GetUserByIdAsync(input.Id);
MapToEntity(input, user);
CheckErrors(await _userManager.UpdateAsync(user));
if (input.RoleNames != null)
{
CheckErrors(await _userManager.SetRoles(user, input.RoleNames));
}
return await Get(input);
}
[HttpDelete]
public override async Task Delete(EntityDto<long> input)
{
var user = await _userManager.GetUserByIdAsync(input.Id);
await _userManager.DeleteAsync(user);
}
[HttpGet]
public async Task<ListResultDto<RoleDto>> GetRoles()
{
var roles = await _roleRepository.GetAllListAsync();
return new ListResultDto<RoleDto>(ObjectMapper.Map<List<RoleDto>>(roles));
}
protected override User MapToEntity(CreateUserDto createInput)
{
var user = ObjectMapper.Map<User>(createInput);
return user;
}
protected override void MapToEntity(UpdateUserDto input, User user)
{
ObjectMapper.Map(input, user);
}
protected override IQueryable<User> CreateFilteredQuery(PagedResultRequestDto input)
{
return Repository.GetAllIncluding(x => x.Roles);
}
protected override async Task<User> GetEntityByIdAsync(long id)
{
var user = Repository.GetAllIncluding(x => x.Roles).FirstOrDefault(x => x.Id == id);
return await Task.FromResult(user);
}
protected override IQueryable<User> ApplySorting(IQueryable<User> query, PagedResultRequestDto input)
{
return query.OrderBy(r => r.UserName);
}
protected virtual void CheckErrors(IdentityResult identityResult)
{
identityResult.CheckErrors(LocalizationManager);
}
}
Edit 2:
Your Get
method has complex input
argument: Get(EntityDto<long> input)
. HTTP GET verb can't pass it to server, that is why ASP.NET Boilerplate has no choice, it decide to assign POST verb instead. Only parameters like /Get?name=Max&age=22
are allowed for GET - at this case method's signature will be like this: Get(string name, int age)
.
So you should leave all of it without changes or change signature to flattern variant, enumerating properties of EntityDto<long>
as comma separated arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With