【问题标题】:REST API - CreatedAtRoute method doesn't return a valueREST API - CreatedAtRoute 方法不返回值
【发布时间】:2017-08-16 11:27:48
【问题描述】:

我正在 .NET Core 中构建一些 REST API 服务器并使用 Postman 软件对其进行测试。当我尝试在 CreateUser 方法内的 DBContext 类上执行第二个 Add 操作时,我遇到了 POST 方法的问题,它没有返回任何值(“无法获得任何响应”)。我的代码:

用户控制器:

[Produces("application/json")]
[Route("api/[controller]")]
public class UsersController : Controller
{
    private readonly DBContext _context;

    #region CONSTRUCTOR

    public UsersController(DBContext context)
    {
        _context = context;
    }

    #endregion

    #region HTTP GET

    // GET: api/users || api/users?cardnr=xxx
    [HttpGet]
    public async Task<IActionResult> GetUsers(string cardNr)
    {
        if (String.IsNullOrEmpty(cardNr))
        {
            try
            {
                var users = await _context.Users.ToListAsync();

                if (users.Any())
                {
                    return Json(users);
                }
                else
                {
                    return NotFound();
                }
            }
            catch (Exception ex)
            {
                Helpers.ExceptionLogger.LogException(ex);
                return StatusCode(500);
            }
        }
        else
        {
            try
            {
                var user = await _context.Users.FirstOrDefaultAsync(u => u.Cards.Any(c => c.CardNumber.Equals(cardNr)));

                if (user == null)
                {
                    return NotFound();
                }
                else
                {
                    return new ObjectResult(user);
                }
            }
            catch (Exception ex)
            {
                Helpers.ExceptionLogger.LogException(ex);
                return StatusCode(500);
            }
        }
    }

    //GET: api/users/1
    [HttpGet("{id}", Name = "GetUserByID")]
    public async Task<IActionResult> GetUserByID(Int32 id)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.IDUser == id);

            if (user == null)
            {
                return NotFound();
            }
            else
            {
                return new ObjectResult(user);
            }
        }
        catch (Exception ex)
        {
            Helpers.ExceptionLogger.LogException(ex);
            return StatusCode(500);
        }
    }

    #endregion

    #region HTTP POST

    [HttpPost]
    public async Task<IActionResult> CreateUser([FromBody] Models.User userToCreate, string userGroupID)
    {
        if (userToCreate == null)
        {
            return BadRequest();
        }
        else
        {
            try
            {
                _context.Users.Add(userToCreate);

                int parsingResult;

                // if user passed userGroupID
                if (userGroupID != null)
                {
                    // parsing if userGroupID is a number
                    if (!int.TryParse(userGroupID, out parsingResult))
                    {
                        return BadRequest();
                    }
                    else
                    {
                        // if client want to assign a new user to some group
                        if (parsingResult > 0)
                        {
                            // creating new record in UserGroup table - assigning a user to group
                            var userGroup = new Models.UserGroup();
                            _context.Entry(userGroup).Property("IDGroup").CurrentValue = parsingResult;
                            _context.Entry(userGroup).Property("IDUser").CurrentValue = userToCreate.IDUser;

                            _context.UserGroups.Add(userGroup); // NOTE HERE
                        }
                    }
                }

                await _context.SaveChangesAsync();

                return CreatedAtRoute("GetUserByID", new { id = userToCreate.IDUser }, userToCreate);
            }
            catch (Exception ex)
            {
                Helpers.ExceptionLogger.LogException(ex);
                return StatusCode(500);
            }
        }
    }

    #endregion
}

用户模型:

public class User
{
    [Key]
    public int IDUser { get; set; }

    [Required]
    public string Name { get; set; }

    public List<UserGroup> UsersGroups { get; set; }
}

用户组模型:

public class UserGroup
{
    public Group Group { get; set; }
    public User User { get; set; }
}

DBContext 类:

public class DBContext : DbContext
{
    public DBContext(DbContextOptions<DBContext> options)
        : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // shadow property - foreign key
        modelBuilder.Entity<UserGroup>()
            .Property<int>("IDUser");

        // shadow property - foreign key
        modelBuilder.Entity<UserGroup>()
            .Property<int>("IDGroup");

        modelBuilder.Entity<UserGroup>()
            .HasKey( new string[]{ "IDUser", "IDGroup" });

        modelBuilder.Entity<UserGroup>()
            .HasOne(ug => ug.Group)
            .WithMany(g => g.UsersGroups)
            .HasForeignKey("IDGroup");

        modelBuilder.Entity<UserGroup>()
            .HasOne(ug => ug.User)
            .WithMany(u => u.UsersGroups)
            .HasForeignKey("IDUser");

        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Group> Groups { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<UserGroup> UserGroups { get; set; }
}

问题在于UsersController 中的HttpPost 方法。 当我执行“正常” POST 并传递包含要添加的用户而不将其分配给组(空 userGroupID 参数)的 JSON 对象时,一切正常 - 用户被添加到数据库中,邮递员返回给我一个带有其 ID 的用户。

屏幕:

当我尝试添加新用户但将其添加到特定组时,我总是收到错误:

屏幕:

即使出现该错误,新用户仍被正确添加到数据库并与其组关联(记录被添加到 UserGroup 表;UserGroup 是用户和组表之间的连接表)。所以我的数据库中有正确的数据,但我总是收到这个错误,我无法将新添加的用户返回给调用 API 并且无法获取他的 ID 的客户端。我的 CreateUser 方法做错了吗?

更新

我在UsersControllerCreateUser 方法的“注意这里”中添加了一个注释行。如果我评论整个这一行,我不会从 Postman 收到错误,但显然我没有让我的用户与其组相关联(我没有将新记录添加到 UserGroup 连接表中)。所以看起来上下文对象上的另一个Add 方法会导致错误......这有意义吗?

【问题讨论】:

    标签: rest http-post entity-framework-core postman


    【解决方案1】:

    你试过调试吗?

    在行上设置断点:

    if (userToCreate == null)
    

    使用 Postman 再次发送请求并调试您的应用。在那里你可以看到哪里出了问题。

    请告诉我进展如何,以便我知道如何帮助你:)

    【讨论】:

    • 你好安德烈。感谢您的回答。是的,我已经尝试调试我的应用程序,if (userToCreate == null) 总是返回 false,这意味着用户被正确传递给 CreateUser 方法。此外,它已正确添加到 DB 并已正确分配给组(UserGroup 表保存正确的新记录)。我仍然有这个 Postman 错误
    猜你喜欢
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2020-07-02
    相关资源
    最近更新 更多