闲话 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,如果请求的用户名不存在,即会返回代码中定义的错误信息


相关文章
|
8天前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
30 5
|
26天前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
38 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
16天前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
24 3
|
2月前
|
Java Maven Docker
gitlab-ci 集成 k3s 部署spring boot 应用
gitlab-ci 集成 k3s 部署spring boot 应用
|
23天前
|
消息中间件 监控 Java
您是否已集成 Spring Boot 与 ActiveMQ?
您是否已集成 Spring Boot 与 ActiveMQ?
46 0
|
5月前
|
监控 druid Java
spring boot 集成配置阿里 Druid监控配置
spring boot 集成配置阿里 Druid监控配置
316 6
|
5月前
|
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. 启动应用,测试流程启动,如通过服务和控制器开始流程实例。 示例代码包括服务类启动流程实例及控制器接口。实际集成需按业务需求调整。
418 4
|
5月前
|
消息中间件 Java 测试技术
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
376 1
|
6月前
|
消息中间件 Java Kafka
springboot集成kafka
springboot集成kafka
185 2
|
5月前
|
消息中间件 Java Kafka
Spring Boot与Apache Kafka Streams的集成
Spring Boot与Apache Kafka Streams的集成