闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子

简介: 闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子

一个在实际应用中 EF Core 集成 FluentValidation 进行数据校验的例子。

  1. 创建一个 Asp.Net Core WebApi 项目
  2. 引用以下 Nuget 包

FluentValidation.AspNetCore

Microsoft.AspNetCore.Identity.EntityFrameworkCore

Microsoft.EntityFrameworkCore.Relational

Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Tools

3.创建 Login 操作方法的请求参数模型类 LoginRequest

// LoginRequest 类只是一个普通的C#类,
// 没有标注任何的Attribute或者实现任何的接口,
// 它的唯一责任就是传递数据
public record LoginRequest(string Email, string Password, string PasswordConfirm);

4.修改 appsettings.json,添加数据库连接字符串

{
  "Logging": {
  "LogLevel": {
    "Default": "Information",
    "Microsoft.AspNetCore": "Warning"
  }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
  "Default": "Server=(localdb)\\mssqllocaldb;Database=IdentityTestDB;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

5.创建用户实体类User和Role

using Microsoft.AspNetCore.Identity;
public class User : IdentityUser<long>
{
  public DateTime CreationTime { get; set; }
  public string? NickName { get; set; }
}
public class Role : IdentityRole<long>
{
}

6.创建继承自IdentityDbContext的上下文类

using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
public class TestDbContext : IdentityDbContext<User, Role, long>
{
  public TestDbContext(DbContextOptions<TestDbContext> options)
    : base(options)
  {
  }
  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
    base.OnModelCreating(modelBuilder);
    modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
  }
}

7.打开 Program.cs,注册 Identity 和 FluentValidation

using FluentValidation;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// 注册标识框架相关的服务,并配置相关选项
IServiceCollection services = builder.Services;
services.AddDbContext<TestDbContext>(opt =>
{
  string connStr = builder.Configuration.GetConnectionString("Default")!;
  opt.UseSqlServer(connStr);
});
services.AddDataProtection();
services.AddIdentityCore<User>(options =>
{
  options.Password.RequireDigit = false;
  options.Password.RequireLowercase = false;
  options.Password.RequireNonAlphanumeric = false;
  options.Password.RequireUppercase = false;
  options.Password.RequiredLength = 6;
  options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
  options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
});
var idBuilder = new IdentityBuilder(typeof(User), typeof(Role), services);
idBuilder.AddEntityFrameworkStores<TestDbContext>()
  .AddDefaultTokenProviders()
  .AddRoleManager<RoleManager<Role>>()
  .AddUserManager<UserManager<User>>();
// 注册 FluentValidation 服务
Assembly assembly = Assembly.GetExecutingAssembly();
builder.Services.AddFluentValidationAutoValidation()
  .AddFluentValidationClientsideAdapters()
  .AddValidatorsFromAssembly(assembly);
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();

8.编写请求参数模型类 LoginRequest

public record LoginRequest(string UserName, string Password);

9.编写继承自AbstractValidator的数据校验类,留意注释

using FluentValidation;
using Microsoft.EntityFrameworkCore;
public class LoginRequestValidator : AbstractValidator<LoginRequest>
{
  // 通过构造方法注入了TestDbContext
  public LoginRequestValidator(TestDbContext dbCtx)
  {
    RuleFor(x => x.UserName)
      .NotNull()
      // 使用TestDbContext服务检查用户名是否存在
      // 同步方式
      .Must(name => dbCtx.Users.Any(u => u.UserName == name))
      // 异步方式,但使用异步后出错,暂时未能找到解决方案
      //.MustAsync((name,_) => dbCtx.Users.AnyAsync(u => u.UserName == name))
      // 用Lambda表达式的形式使用模型类中的属性对报错信息进行格式化
      .WithMessage(c => $"用户名{c.UserName}不存在");
  }
}

10.打开登录请求控制器,编写 Login API

using Microsoft.AspNetCore.Mvc;
namespace FluentValidationSample2.Controllers
{
  [ApiController]
  [Route("[controller]/[action]")]
  public class TestController : ControllerBase
  {
    [HttpPost]
    public ActionResult Login(LoginRequest req)
    {
      return Ok();
    }
  }
}

11.在 Postman 或 Swagger 测试 Login API,如果请求的用户名不存在,即会返回代码中定义的错误信息


相关文章
|
5天前
|
开发框架 NoSQL .NET
利用分布式锁在ASP.NET Core中实现防抖
【9月更文挑战第5天】在 ASP.NET Core 中,可通过分布式锁实现防抖功能,仅处理连续相同请求中的首个请求,其余请求返回 204 No Content,直至锁释放。具体步骤包括:安装分布式锁库如 `StackExchange.Redis`;创建分布式锁服务接口及其实现;构建防抖中间件;并在 `Startup.cs` 中注册相关服务和中间件。这一机制有效避免了短时间内重复操作的问题。
|
3天前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
11 0
|
14天前
|
开发框架 监控 .NET
开发者的革新利器:ASP.NET Core实战指南,构建未来Web应用的高效之道
【8月更文挑战第28天】本文探讨了如何利用ASP.NET Core构建高效、可扩展的Web应用。ASP.NET Core是一个开源、跨平台的框架,具有依赖注入、配置管理等特性。文章详细介绍了项目结构规划、依赖注入配置、中间件使用及性能优化方法,并讨论了安全性、可扩展性以及容器化的重要性。通过这些技术要点,开发者能够快速构建出符合现代Web应用需求的应用程序。
28 0
|
18天前
|
开发框架 监控 .NET
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
|
18天前
|
Linux C# C++
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
|
2月前
|
监控 druid Java
spring boot 集成配置阿里 Druid监控配置
spring boot 集成配置阿里 Druid监控配置
159 6
|
2月前
|
Java 关系型数据库 MySQL
如何实现Springboot+camunda+mysql的集成
【7月更文挑战第2天】集成Spring Boot、Camunda和MySQL的简要步骤: 1. 初始化Spring Boot项目,添加Camunda和MySQL驱动依赖。 2. 配置`application.properties`,包括数据库URL、用户名和密码。 3. 设置Camunda引擎属性,指定数据源。 4. 引入流程定义文件(如`.bpmn`)。 5. 创建服务处理流程操作,创建控制器接收请求。 6. Camunda自动在数据库创建表结构。 7. 启动应用,测试流程启动,如通过服务和控制器开始流程实例。 示例代码包括服务类启动流程实例及控制器接口。实际集成需按业务需求调整。
180 4
|
2月前
|
消息中间件 Java 测试技术
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
132 1
|
3月前
|
消息中间件 Java Kafka
springboot集成kafka
springboot集成kafka
118 2
|
2月前
|
消息中间件 Java Kafka
Spring Boot与Apache Kafka Streams的集成
Spring Boot与Apache Kafka Streams的集成