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


相关文章
|
2月前
|
SQL 程序员
分享一个 .NET 通过监听器拦截 EF 消息写日志的详细例子
分享一个 .NET 通过监听器拦截 EF 消息写日志的详细例子
|
2月前
|
jenkins 测试技术 持续交付
解锁.NET项目高效秘籍:从理论迷雾到实践巅峰,持续集成与自动化测试如何悄然改变游戏规则?
【8月更文挑战第28天】在软件开发领域,持续集成(CI)与自动化测试已成为提升效率和质量的关键工具。尤其在.NET项目中,二者的结合能显著提高开发速度并保证软件稳定性。本文将从理论到实践,详细介绍CI与自动化测试的重要性,并以ASP.NET Core Web API项目为例,演示如何使用Jenkins和NUnit实现自动化构建与测试。每次代码提交后,Jenkins自动触发构建流程,通过编译和运行NUnit测试确保代码质量。这种方式不仅节省了时间,还能快速发现并解决问题,推动.NET项目开发迈向更高水平。
40 8
|
29天前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
39 0
|
2月前
|
Java Spring UED
Spring框架的异常处理秘籍:打造不败之身的应用!
【8月更文挑战第31天】在软件开发中,异常处理对应用的稳定性和健壮性至关重要。Spring框架提供了一套完善的异常处理机制,包括使用`@ExceptionHandler`注解和配置`@ControllerAdvice`。本文将详细介绍这两种方式,并通过示例代码展示其具体应用。`@ExceptionHandler`可用于控制器类中的方法,处理特定异常;而`@ControllerAdvice`则允许定义全局异常处理器,捕获多个控制器中的异常。
39 0
|
2月前
|
存储 开发框架 .NET
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
|
2月前
|
程序员 数据库
分享 2 个 .NET EF 6 只更新某些字段的方法
分享 2 个 .NET EF 6 只更新某些字段的方法
|
2月前
|
数据库
分享一个 .NET EF 6 扩展 Where 的方法
分享一个 .NET EF 6 扩展 Where 的方法
|
2月前
|
SQL 程序员 数据库
总结查看 .NET EF 生成的 SQL 的 3 种方式,亲测可用
总结查看 .NET EF 生成的 SQL 的 3 种方式,亲测可用
|
3月前
|
监控 druid Java
spring boot 集成配置阿里 Druid监控配置
spring boot 集成配置阿里 Druid监控配置
196 6
|
3月前
|
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. 启动应用,测试流程启动,如通过服务和控制器开始流程实例。 示例代码包括服务类启动流程实例及控制器接口。实际集成需按业务需求调整。
220 4
下一篇
无影云桌面