如何验证ASP.NET CORE API中电子邮件属性是否唯一?

时间:2019-06-12 15:22:09

标签: c asp.net-web-api asp.net-core

我需要在服务器端发布帖子或进行验证,以检查电子邮件是否唯一。

在研究中,我一直做的例子是传统的MVC应用程序,而不是api。

在许多情况下,我看到[Remote] https://docs.microsoft.com/pt-br/aspnet/core/mvc/models/validation?view=aspnetcore-2.2#remote-attribute。我尝试根据文档实施,但是调试验证了控制器中的函数均未调用。

User.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Mvc;

namespace Base.Models
{
    [Table("users")]
    public partial class User
    {
        ...
        [Required]
        [EmailAddress]
        [Remote(action: "VerifyEmail", controller: "UserController",ErrorMessage="Email already in use")]
        [Column("email", TypeName = "varchar(254)")]
        public string Email { get; set; }
        ...
    }
}

UserController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Base.Models;

namespace Base.Controllers
{
    [Route("api/users")]
    [ApiController]
    public class UserController : Controller
    {
        ...
        [AcceptVerbs("Get")]
        public IActionResult VerifyEmail(string email)
        {
            //forcing it to go wrong
            return Json($"Email {email} is already in use.");
        }
        ...
    }
}

有人知道如何实现吗?

2 个答案:

答案 0 :(得分:1)

我无法发表评论,因为我缺乏足够的声誉,如果我有时间,我会去验证一下,但是我认为您的问题是[Route(“ api / users”)]。 您为装饰器指定了控制器名称,但该控制器位于其他路由之后。容易调试的方法是暂时删除Route或将“ VerifyEmail”操作放到另一个您不想改变其路由的控制器上。

答案 1 :(得分:0)

看到它没有进展,我决定进行个性化验证。

EmailUserUniqueAttribute.cs

foreach($arr as $sub){
    $res[][key($sub[0]) . "s"] = array_column($sub, 'userid');
}

var_dump($res);

User.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using Base.Models;

namespace Core.Models
{
    public class EmailUserUniqueAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(
            object value, ValidationContext validationContext)
        {
            var _context = (AppDbContext)validationContext.GetService(typeof(AppDbContext));
            var entity = _context.Users.SingleOrDefault(e => e.Email == value.ToString());

            if (entity != null)
            {
                return new ValidationResult(GetErrorMessage(value.ToString()));
            }
            return ValidationResult.Success;
        }

        public string GetErrorMessage(string email)
        {
            return $"Email {email} is already in use.";
        }
    }
}

Assimestáfuncionando,这样的问题就解决了。