检查数据库中现有记录时的意外行为
Unexpected behavior when checking for existing records in the database
我有一个 ASP.NET CORE 2.1 API 后端和一个 Ember 前端(在 VSCode 中创建)。我正在关注来自 Embercasts 的新用户注册在线视频教程。检查重复用户的逻辑工作不正常:
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 1)
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}
出于某种原因,上面的代码在报告重复用户之前只允许一个重复用户。换句话说,未达到 return 警告用户重复记录的新 ValidationResult 的代码。我认为这可能与一些奇怪的数组索引问题有关,其中第一条记录位于位置 0。在测试该假设后,我被证明是正确的。以下代码可防止重复,同时仍允许创建一条记录:
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 0)
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}
有谁知道为什么会这样?感谢任何帮助。
LibraryApi\Model\User.cs
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using JsonApiDotNetCore.Models;
namespace LibraryApiNew.Models
{
public class User : Identifiable
{
[Attr("email"), UniqueEmail, Required(AllowEmptyStrings = false)]public string Email {get; set; }
[Attr("username"), UniqueUsername, Required(AllowEmptyStrings = false)]public string Username { get; set; }
[Attr("password"), NotMapped, Required(AllowEmptyStrings = false), Compare("PasswordConfirmation")]public string Password { get; set; }
[Attr("password-confirmation"), NotMapped, Required(AllowEmptyStrings = false)]public string PasswordConfirmation { get; set; }
public string PasswordHash { get; set; }
}
public class UniqueUsername : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var context = (AppDbContext) validationContext.GetService(typeof(AppDbContext));
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 0) // Why?
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}
return ValidationResult.Success;
}
}
public class UniqueEmail : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var context = (AppDbContext) validationContext.GetService(typeof(AppDbContext));
if (context.Users.Where(u => u.Email.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 0) // Why?
{
return new ValidationResult("Email is already taken", new [] { "Email" });
}
return ValidationResult.Success;
}
}
}
您的代码与用户注册相关,带有 context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 0
的 if 子句会检查用户名是否已经存在。
如果它存在,创建第二个将创建一个副本,因此出现错误消息 "Username is already taken"。
如果计数为 0,则仅表示该名称尚未被使用且可以使用且验证成功。
现在你会检查 > 1
,这意味着你愿意允许一个重复的
我知道这应该放在评论中,但我没有那么高的声誉所以总结一下你的检查。
您可以将检查更改为
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() >= 1)
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}
另一种不会误导您的检查方式是
if (context.Users.Any(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)))
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}
我有一个 ASP.NET CORE 2.1 API 后端和一个 Ember 前端(在 VSCode 中创建)。我正在关注来自 Embercasts 的新用户注册在线视频教程。检查重复用户的逻辑工作不正常:
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 1)
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}
出于某种原因,上面的代码在报告重复用户之前只允许一个重复用户。换句话说,未达到 return 警告用户重复记录的新 ValidationResult 的代码。我认为这可能与一些奇怪的数组索引问题有关,其中第一条记录位于位置 0。在测试该假设后,我被证明是正确的。以下代码可防止重复,同时仍允许创建一条记录:
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 0)
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}
有谁知道为什么会这样?感谢任何帮助。
LibraryApi\Model\User.cs
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using JsonApiDotNetCore.Models;
namespace LibraryApiNew.Models
{
public class User : Identifiable
{
[Attr("email"), UniqueEmail, Required(AllowEmptyStrings = false)]public string Email {get; set; }
[Attr("username"), UniqueUsername, Required(AllowEmptyStrings = false)]public string Username { get; set; }
[Attr("password"), NotMapped, Required(AllowEmptyStrings = false), Compare("PasswordConfirmation")]public string Password { get; set; }
[Attr("password-confirmation"), NotMapped, Required(AllowEmptyStrings = false)]public string PasswordConfirmation { get; set; }
public string PasswordHash { get; set; }
}
public class UniqueUsername : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var context = (AppDbContext) validationContext.GetService(typeof(AppDbContext));
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 0) // Why?
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}
return ValidationResult.Success;
}
}
public class UniqueEmail : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var context = (AppDbContext) validationContext.GetService(typeof(AppDbContext));
if (context.Users.Where(u => u.Email.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 0) // Why?
{
return new ValidationResult("Email is already taken", new [] { "Email" });
}
return ValidationResult.Success;
}
}
}
您的代码与用户注册相关,带有 context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 0
的 if 子句会检查用户名是否已经存在。
如果它存在,创建第二个将创建一个副本,因此出现错误消息 "Username is already taken"。
如果计数为 0,则仅表示该名称尚未被使用且可以使用且验证成功。
现在你会检查 > 1
,这意味着你愿意允许一个重复的
我知道这应该放在评论中,但我没有那么高的声誉所以总结一下你的检查。
您可以将检查更改为
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() >= 1)
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}
另一种不会误导您的检查方式是
if (context.Users.Any(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)))
{
return new ValidationResult("Username is already taken", new [] { "Username" });
}