开发用户收藏商品功能遇400错误:Invalid user ID format求助
收藏商品功能触发"Invalid user ID format"错误排查
问题描述
开发商城用户收藏商品功能,需求支持:用户可收藏多个商品,一个商品可被多个用户收藏。但Postman测试请求时,触发代码中第三个if条件,返回400 Bad Request错误,提示“Invalid user ID format”。尽管User实体的Id为int类型,调试发现userString的值为"saymon",且用户已登录。
相关代码
实体类代码
public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } [ForeignKey("UserId")] public User User { get; set; } public int UserId { get; set; } } public class User { public int Id { get; set; } public string UserName { get; set; } public byte[] PasswordHash { get; set; } public byte[] PasswordSalt { get; set; } public List<Product> Products { get; set; } public List<Product> LikedProducts { get; set; } = new List<Product>(); }
控制器端点代码
[HttpPost("add-to-favorites/{productId}")] public async Task<ActionResult> AddToFavorites(int productId) { var userString = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; var product = await _productRepository.GetProductById(productId); if (product == null) { return NotFound(); } if (product.UserId.ToString() == userString) { return BadRequest("You cannot like your own product."); } if (!int.TryParse(userString, out int id)) { return BadRequest("Invalid user ID format."); } var user = await _userRepository.GetUser(id); user.LikedProducts.Add(product); await _context.SaveChangesAsync(); return Ok(); }
错误原因
- Claim值错误:
ClaimTypes.NameIdentifier对应的Claim存储的是用户名("saymon"),而非用户的int类型ID,导致int.TryParse解析失败,触发格式错误提示。 - 逻辑判断无效:
product.UserId.ToString() == userString的比较逻辑完全错误——一边是商品所属用户的ID字符串,一边是当前登录用户的用户名,两者永远不可能相等,这个判断毫无意义。 - 多对多关系设计缺陷:当前实体中
User.LikedProducts的设计是一对多关联,不符合“一个商品可被多个用户收藏”的需求,会导致一个商品只能被单个用户收藏。
解决建议
1. 修正Claim获取逻辑
确保用户登录时,将用户的int类型ID存入ClaimTypes.NameIdentifier(或使用自定义Claim类型):
- 如果使用JWT认证,在生成Token时添加正确的Claim:
var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Name, user.UserName) }; - 后续从Claim中获取的就是用户ID的字符串形式,能正常解析为int。
2. 修复用户判断逻辑
拿到解析后的用户ID后,直接和product.UserId做int类型比较,无需转字符串:
var userString = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (string.IsNullOrEmpty(userString)) { return Unauthorized(); // 未正确获取用户信息,返回未授权 } if (!int.TryParse(userString, out int userId)) { return BadRequest("Invalid user ID format."); } var product = await _productRepository.GetProductById(productId); if (product == null) { return NotFound(); } if (product.UserId == userId) { return BadRequest("You cannot like your own product."); }
3. 修正多对多关系设计
使用EF Core的多对多配置,创建中间表来维护用户和收藏商品的关联:
- 在DbContext的
OnModelCreating方法中添加配置:protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>() .HasMany(u => u.LikedProducts) .WithMany() // 如果需要反向导航,可在Product中添加List<User> LikedByUsers,此处改为.WithMany(p => p.LikedByUsers) .UsingEntity(j => j.ToTable("UserLikedProducts")); }
这样就能实现一个用户收藏多个商品、一个商品被多个用户收藏的需求。
内容的提问来源于stack exchange,提问作者szymix1322
相关产品推荐
相关产品推荐

