尝试确保 ASP.Net 中仅存在一个电子邮件实例。有没有更好的方法?

Trying to make sure that no more than one instance of an email exists in ASP.Net. Is there a better way of doing this?

提问人:Literal Garbage 提问时间:3/15/2023 更新时间:3/15/2023 访问量:33

问:

我正在尝试查询数据库中所有拥有特定电子邮件的购物者,以阻止服务器创建具有重复电子邮件的购物者。如果查询为空,则意味着服务器可以继续创建新的购物者。问题是我的解决方案是基于抛出异常的函数 请看下面的代码:System.Linq.ThrowHelper.ThrowNoElementsException()

public async Task<Shopper?> GetByEmailAsync(string email)
{
     try
     {
         var shopper = await _shoppersCollection.Find(x => x.Email == email).FirstAsync();
         return shopper;
     }
     catch (System.Exception e)
     {
         return null;
     }
}

此函数在以下函数中调用:

async public Task<Boolean> ValidateEmail(string email)
{
    var shopperWithEmail = await GetByEmailAsync(email);

    if (shopperWithEmail == null)
    {
        return false;
    }
    else
    {
        return true;
    }
}

该函数在控制器的此函数中用于验证给定的电子邮件:

[HttpPost]
public async Task<IActionResult> Post(Shopper newShopper)
{
    if (await _shoppersService.ValidateEmail(newShopper.Email)!)
        return StatusCode(409, new { message = "Email is already in use." });

    await _shoppersService.CreateAsync(newShopper);

    return CreatedAtAction(nameof(Get), new { id = newShopper.Id }, newShopper);
}

我的观点是,如果觉得我的实现很糟糕;解决这个问题必须比抓住异常更好,因为我被告知这是不好的做法。我在互联网上搜索了无济于事,也无法破译文档。任何建议都是值得赞赏的,即使只是一般的提示,与问题并不严格相关。

谢谢。

asp.net ASP.NET-MVC MONGODB 验证 mongodb-query

评论

2赞 user20042973 3/15/2023
'阻止服务器使用重复的电子邮件创建购物者' - 听起来您正在寻找创建一个唯一的索引(并且应用程序代码在尝试插入时应检查响应,以便它可以适当地响应来自用户的请求)

答:

1赞 Bin Rohan 3/15/2023 #1

你可以像这样编写第一种方法。

public async Task<Shopper?> GetByEmailAsync(string email)
{
     
    return await _shoppersCollection.FirstOrDefaultAsync(x => x.Email == email);
    
}

因此,无需添加块。因为如果没有给定电子邮件的购物者,FirstOrDefaultAsync() 将返回 null。trycatch

我的建议是改变第二种方法,这样它更有意义。

async public Task<Boolean> IsEmailInUse(string email)
{
    var shopper = await GetByEmailAsync(email);
    
    return shopper == null ? false : true;
}

其余代码:

[HttpPost]
public async Task<IActionResult> Post(Shopper newShopper)
{
    if (!await _shoppersService.IsEmailInUse(newShopper.Email)!)
        return StatusCode(409, new { message = "Email is already in use." });

    await _shoppersService.CreateAsync(newShopper);

    return CreatedAtAction(nameof(Get), new { id = newShopper.Id }, newShopper);
}

评论

1赞 Literal Garbage 3/15/2023
匪夷所思!这正是我想要做的,找不到合适的功能。至于草率的代码,我在写这篇文章时就意识到这是一场灾难。总之,非常感谢!
0赞 jeffsdata 3/20/2023
另一种选择是使用“Any”,如果您只想返回与列表中的电子邮件匹配的任何电子邮件的布尔值。return await _shoppersCollection.Any(x => x.Email == email);
1赞 Bin Rohan 3/20/2023
@jeffsdata,我同意你的看法,我忘记了使用它来简化代码并将其减少为一行。如果 在控制器中可访问,则可能不需要其他方法来抽象代码Any_shoppersCollection