简体   繁体   中英

ASP.NET Core Web API - Fluent Validation not working as expected

I am implementing Fluent Validation for user registration in ASP.NET Core-6 web API. These are my codes

ApplicationUser:

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MobileNumber { get; set; }

    [DefaultValue(false)]
    public bool? IsAdmin { get; set; }
}

Then I have the DTOs:

public class AdminCreateDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
    public string MobileNumber { get; set; }
    public string Password { get; set; }
}

public class AdminUserDto
{
    public string Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string UserName { get; set; }
    public bool? IsAdmin { get; set; }
    public string MobileNumber { get; set; }
}

I validated the fields in the model through the DTO shown below:

public class LoginRequestDtoValidator : AbstractValidator<LoginRequestDto>
{
    public LoginRequestDtoValidator()
    {
        RuleFor(user => user.UserName)
            .NotNull()
            .NotEmpty().WithMessage("Username field is required.");

        RuleFor(user => user.Password)
            .NotNull()
            .NotEmpty().WithMessage("Password field is required.");
    }
}

Fluent Validator Injection:

services.AddTransient<IValidator<LoginRequestDto>, LoginRequestDtoValidator>();

Then the service. Both the interface and the implementation.

public interface IAdminUserService
{
    Task<Response<AdminUserDto>> CreateAdminUserAsync(AdminCreateDto adminDto);
}

public async Task<Response<AdminUserDto>> CreateAdminUserAsync(AdminCreateDto model)
{
    var existingUser = await _userManager.FindByNameAsync(model.UserName);
    var response = new Response<AdminUserDto>();
    using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
    {
        if (existingUser == null)
        {
            var user = _mapper.Map<ApplicationUser>(model);
            user.IsAdmin = true;
            var result = await _userManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                await _userManager.AddToRoleAsync(user, UserRoles.Admin);
                    transaction.Complete();
                    return response;
            }
        }
        else
        {
            _logger.Information("Admin User Registration failed");
            return response;
        }
        transaction.Complete();
        return response;
    }
}

Finally, the controler:

[HttpPost]
[Route(register)]
public async Task<ActionResult<Response<AdminUserDto>>> CreateAdminUserAsync([FromBody] AdminCreateDto model)
{
    _logger.LogInformation($"Registration Attempt for {model.UserName}");
    var result = await _adminUserService.CreateAdminUserAsync(model);
    return StatusCode(result.StatusCode, result);
}

Program.cs:

var builder = WebApplication.CreateBuilder(args);
ConfigurationManager configuration = builder.Configuration;
var environment = builder.Environment;

builder.Services.AddHttpContextAccessor();
builder.Services.AddHttpClient();

builder.Services.AddControllers()
                .AddFluentValidation(options =>
                {
                    // Validate child properties and root collection elements
                    options.ImplicitlyValidateChildProperties = true;
                    options.ImplicitlyValidateRootCollectionElements = true;
                    options.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly());
                    options.AutomaticValidationEnabled = true;
                });

// Configure AutoMapper
builder.Services.ConfigureAutoMappers();
builder.Services.AddDependencyInjection();

var app = builder.Build();

app.MapControllers();
app.Run();

When I did not enter anything in the UserName and Password fields, the custom messages in the Validator were not display. It suppose to display the messages to notify user of validation issue.

Where did I get it wrong?

Thanks

I guess you forgot registering your validation class...

I don't know what you used like AddControllers, AddControllersWithViews or.., you can handle it.

 services.AddControllersWithViews()
   .AddFluentValidation(fv => {
    fv.RegisterValidatorsFromAssemblyContaining<LoginRequestDtoValidator >();
   }
                               

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM