How to validate if email attribute is unique in an ASP .NET CORE API?

别来无恙 提交于 2021-01-29 18:22:10

问题


I was needing to make a post or put a validation on the server side to check if the email is unique.

In the research I have always done the example was a traditional MVC application and never an api.

In many cases I saw that the [Remote] https://docs.microsoft.com/pt-br/aspnet/core/mvc/models/validation?view=aspnetcore-2.2#remote-attribute . I tried to implement according to the documentation, but debugging verified that the function in the controller is neither called.

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.");
        }
        ...
    }
}

Anyone have any idea how to implement this?


回答1:


Seeing that it was not progressing, I decided to do a personalized validation.

EmailUserUniqueAttribute.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.";
        }
    }
}

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]
        [EmailUserUnique]
        [Column("email", TypeName = "varchar(254)")]
        public string Email { get; set; }
    }
}
        ...

It works, but I don't know if this is the best way to do this.




回答2:


I cant comment cause I lack the sufficient reputation, and if I had time I would had gone and verified but I think your issue here is the [Route("api/users")]. You are giving your decorator the Controller name but that controller is behind a different route. Easy debug of that will be to remove the Route temporarily OR put the "VerifyEmail" action to another controller that you arent altering its route.



来源:https://stackoverflow.com/questions/56565612/how-to-validate-if-email-attribute-is-unique-in-an-asp-net-core-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!