首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检查数据库中现有记录时的意外行为

检查数据库中现有记录时的意外行为
EN

Stack Overflow用户
提问于 2018-10-13 18:45:22
回答 2查看 74关注 0票数 0

我有一个带有Ember前端的ASP.NET核心2.1API后端(用VSCode创建)。我是跟随一个在线视频教程从Embercast为新用户注册。检查重复用户的逻辑不能正常工作:

代码语言:javascript
复制
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 1)
{
     return new ValidationResult("Username is already taken", new [] { "Username" });
}

由于某些原因,上面的代码允许在报告重复用户之前准确地使用一个重复的用户。换句话说,没有到达返回新的ValidationResult通知用户重复记录的代码。我认为这可能与某些奇怪的数组索引问题有关,第一个记录位于0位置。在验证了这个假设之后,我被证明是正确的。以下代码防止重复,同时仍然允许创建一条记录:

代码语言:javascript
复制
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

代码语言:javascript
复制
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;
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-13 19:03:02

您的代码与用户注册有关,带有context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() > 0的if子句确实检查用户名是否已经存在。

如果它存在,创建第二个将创建一个副本,因此错误消息“用户名已经被接受”。

如果计数为0,这仅仅意味着还没有使用该名称,并且可以使用该名称,并且验证成功。

现在你能检查一下> 1吗,这意味着你愿意允许一个副本

票数 4
EN

Stack Overflow用户

发布于 2018-10-13 19:06:32

我知道这应该写在评论里,但是我没有那么多的声誉来总结你的支票。

您可以将您的支票更改为

代码语言:javascript
复制
if (context.Users.Where(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)).Count() >= 1)
{
     return new ValidationResult("Username is already taken", new [] { "Username" });
}

另一个代替你支票的方法是不会误导你的

代码语言:javascript
复制
if (context.Users.Any(u => u.Username.Equals((string) value, StringComparison.OrdinalIgnoreCase)))
{
     return new ValidationResult("Username is already taken", new [] { "Username" });
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52796165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档