【问题标题】:ASP.NET Boilerplate: Get and GetAll is POST instead of GET methodASP.NET 样板:Get 和 GetAll 是 POST 而不是 GET 方法
【发布时间】:2018-04-03 03:34:22
【问题描述】:

我正在使用 ASP.NET Boilerplate 框架来做一个小项目,并使用 Swagger UI 集成来检查项目中的 API。我注意到 GetGetAll 仍在使用 POST 方法,而其他人则在各自的 HTTP 动词中,例如 Create 是 POST,Edit 是 UPDATE 等...我阅读了文档并尝试了什么他们在这个[文档]中提出了建议 (https://aspnetboilerplate.com/Pages/Documents/Dynamic-Web-API#http-verbs)

编辑 1: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);
    }
}

编辑 2:

【问题讨论】:

  • 抱歉,我已经编辑了问题,是的,我已经在 Web Api 模块中添加了WithConventionalVerbs
  • 是 Asp.Net Core 吗?
  • 不,我正在使用 Asp.Net MVC
  • 将您的 ABP 版本添加到问题中
  • @DaveL 请编辑代码以增加可读性并保留您遇到问题的方法。

标签: c# asp.net aspnetboilerplate


【解决方案1】:

您的Get 方法具有复杂 input 参数:Get(EntityDto&lt;long&gt; input)。 HTTP GET 动词无法将其传递给服务器,这就是 ASP.NET Boilerplate 没有选择的原因,它决定改为分配 POST 动词。 GET 只允许使用像 /Get?name=Max&amp;age=22 这样的参数 - 在这种情况下,方法的签名将如下所示:Get(string name, int age)

因此,您应该保持所有内容不变或将签名更改为扁平变体,将EntityDto&lt;long&gt; 的属性枚举为逗号分隔的参数。

【讨论】:

  • 不正确,我正在使用EntityDto&lt;long&gt;EntityDto&lt;string&gt;EntityDto&lt;int&gt;。它的Get 方法。
  • @viveknuna,非常有趣。您能否在其中一种方法上向我们展示您扩展后的招摇 UI(带有参数描述)?
【解决方案2】:

您必须将 Http Verb 属性写入接口。不是方法实现!

public interface IUserAppService: IApplicationService
{
    [HttpGet]
    GetUserOutput Get(GetInput input);

    [HttpGet]
    GetAllOutput GetAll(GetAllInput input);    
}

IAsyncCrudAppService

PS:对于来自base的方法,你可以在你的界面中新建它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    相关资源
    最近更新 更多