I have a dto:
using Microsoft.AspNetCore.Mvc;
using ProductManager.Core.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ContactsManager.Core.DTO
{
public class RegisterDTO
{
[MinLength(3), MaxLength(30)]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Name can't be blank")]
public string PersonName { get; set; } = "";
[Required(ErrorMessage = "Email can't be blank")]
[MinLength(3), MaxLength(30)]
[DataType(DataType.Text)]
[EmailAddress(ErrorMessage = "Email should be in a proper email address format")]
// need to download view features
[Remote(action: "IsEmailAlreadyRegistered", controller: "AccountsController", ErrorMessage = "User with this email already exists /remote!")]
public string Email { get; set; } = "";
[Required(ErrorMessage = "Phone can't be blank")]
[MinLength(3), MaxLength(30)]
[RegularExpression("^[0-9]*$", ErrorMessage = "Phone number should contain numbers only")]
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; } = "";
[Required(ErrorMessage = "Password can't be blank")]
[MinLength(3), MaxLength(30)]
[DataType(DataType.Password)]
public string Password { get; set; } = "";
[Required(ErrorMessage = "Confirm Password can't be blank")]
[MinLength(3), MaxLength(30)]
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; } = "";
public UserTypeOptions UserType { get; set; } = UserTypeOptions.User;
}
}
then controller:
using ContactsManager.Core.DTO;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using ProductManager.Core.Domain.Entities.IdentityEntities;
using ProductManager.Core.Enums;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace UserManager.UI.Controllers
{
[Route("[controller]/[action]")]
public class AccountsController : Controller
{
// working on endpoints
private readonly UserManager<AppUser> _userManager;
private readonly SignInManager<AppUser> _signInManager;
private readonly RoleManager<AppRole> _roleManager;
public AccountsController(UserManager<AppUser> userManager, SignInManager<AppUser> signInManager, RoleManager<AppRole> roleManager)
{
_userManager = userManager;
_signInManager = signInManager;
_roleManager = roleManager;
}
[HttpPost]
public async Task<IActionResult> Register(RegisterDTO registerDTO)
{
//Check for validation errors
if (ModelState.IsValid == false)
{
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
return BadRequest(new { Errors = errors });
}
// creating a new user
AppUser user = new AppUser() { Email = registerDTO.Email, PhoneNumber = registerDTO.Phone, UserName = registerDTO.Email, PersonName = registerDTO.PersonName };
// check if it is admin
if(registerDTO.UserType == UserTypeOptions.Admin)
{
// create admin role
if( await _roleManager.FindByNameAsync(UserTypeOptions.Admin.ToString()) is null ) {
}
}
// adding new user
IdentityResult result = await _userManager.CreateAsync(user, registerDTO.Password);
if (result.Succeeded)
{
return Ok(new { Message = "User registered successfully" });
}
else
{
var errors = result.Errors.Select(e => e.Description).ToList();
return BadRequest(new { Errors = errors });
}
}
[HttpPost]
public async Task<IActionResult> Login(LoginDTO loginDTO, string? ReturnUrl)
{
//Check for validation errors
if (!ModelState.IsValid)
{
var errors = ModelState.Values.SelectMany(temp => temp.Errors).Select(temp => temp.ErrorMessage);
return BadRequest(new { Errors = errors });
}
// try to log in
var result = await _signInManager.PasswordSignInAsync(loginDTO.Email, loginDTO.Password, isPersistent: false, lockoutOnFailure: false);
if (!result.Succeeded) { return Unauthorized(new { Message = "Invalid login attempt" }); }
// check if the user need to be returned to the site user was using
if (!string.IsNullOrEmpty(ReturnUrl) && Url.IsLocalUrl(ReturnUrl))
{
return LocalRedirect(ReturnUrl);
}
// loggin
return Ok(new { Message = "Login successful" });
}
[HttpPost]
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
return Ok("Logged out");
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> IsEmailAlreadyRegistered(string email)
{
AppUser? user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
return Json(true); //valid
}
else
{
return Json(false); //invalid
}
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> DoesItWork(string email)
{
return Json(false);
}
}
}
and program.cs
using CRUDExample;
using Microsoft.EntityFrameworkCore;
using ProductsManager.Infrastructure;
var builder = WebApplication.CreateBuilder(args);
// Adding Entity Framework
builder.Services.AddDbContext<EntityDbContext>(options => {
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
//
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.ConfigureServices(builder.Configuration);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
/*app.UseAuthorization();*/
app.MapControllers();
app.Run();
and the problem is that
[Remote(action: "IsEmailAlreadyRegistered", controller: "AccountsController", ErrorMessage = "User with this email already exists /remote!")]
doesnt get invoked. All other validation attributes works, but the remote validation doesnt. I set the breakpoint, then send a data from a SwaggerUI and still it doesnt work.
I dont have a fronetend yet, i send the API calls from swagger. I have no idea why.