- 博客(99)
- 收藏
- 关注
原创 ASP.NET Core用MediatR实现领域事件
如果使用await来调用Publish,程序会等待所有事件处理者的Handle方法执行完成才继续向后执行,因此事件发布者和事件处理者的代码是运行在相同的调用堆栈中的,这样可以轻松实现强一致性的事务。如果不需要等待事件处理者的执行,可以不使用await来在调用Publish;即使使用await调用Publish发布事件,如果某个事件处理者的代码执行太耗时,为避免影响用户体验,可以在事件处理者的Handle方法中异步执行事件的处理逻辑。事件的发布和事件的处理之间解耦。一个发布者对应一个处理者。
2025-02-12 04:35:51
751
原创 DDD聚合在 ASP.NET Core中的实现
比如实体类和数据表具有直接的对应关系,实体类中属性和数据表中的列几乎完全一致。应该不考虑数据库实现的情况下进行领域模型建模,然后再使用Fluent API等对实体类和数据库之间做适配。在实现的时候,可能需要对建模进行妥协性修改,但是这不应该在最开始被考虑。如果一个微服务中有多个聚合根,那么是每个聚合根的实体放到一个单独的上下文中,还是把所有实体放到同一个上下文中?各自的优缺点是什么?定义一个不包含任何成员的标识接口,比如IAggregateRoot,然后要求所有的聚合根实体类都实现这个接口。
2025-02-12 01:52:50
537
原创 EF Core中实现值对象
目前版本,如果需要进行数据筛选,值对象的属性不能直接进行相等比较,只能把值对象的各个属性逐个进行比较,如果属性较多或需要相等比较的代码较多的话,操作会比较麻烦,可以构建表达式树来生成一个进行相等比较的表达式,从而简化EF Core中值对象的比较。对于直接操作数据库的人员来讲,0、1、2这样的值没有“CNY”(人民币)、“USD”(美元)、“NZD”(新西兰元)等这样的字符串类型值可读性更强。在EF Core中,实体的属性可以定义为枚举类型,把枚举类型的值配置成保存为字符串。
2025-02-11 15:30:45
316
原创 EF Core中充血模型的实现
EF Core中提供了“支持字段”(backing field)来支持这种写法:在配置实体类的代码中,使用HasField(“成员变量名”)来配置属性。实现方式2:实体类中不定义无参构造方法,只定义有意义的有参构造方法,但是要求构造方法中的参数的名字和属性的名字一致。实现:把属性的set定义为private或者init,然后通过构造方法为这些属性赋予初始值。原理: EF Core中的实体类如果没有无参的构造方法,则有参的构造方法中的参数的名字。属性是只读的或者是只能被类内部的代码修改。
2025-02-11 14:39:10
123
原创 EF Core对实体属性操作的秘密
基于性能和对特殊功能支持的考虑,EF Core在读写属性的时候,如果可能,它会直接跳过get、set,而直接操作真正存储属性值的成员变量。EF Core是通过实体对象的属性的get、set来进行属性的读写吗?为EF Core实现充血模型做准备。
2025-02-11 13:56:34
305
原创 ASP.NET Core DDD
所有代码都放到同一个应用程序中优点:结构简单;部署简单。缺点:耦合;技术栈统一,软件包版本锁定;一崩全崩;升级周期长;无法局部扩容。DDD(Domain-driven design,领域驱动设计)是一个很好的应用于微服务架构的方法论。在项目的全生命周期内,所有岗位的人员都基于对业务的相同的理解来开展工作。所有人员站在用户的角度、业务的角度去思考问题,而不是站在技术的角度去思考问题。
2025-02-11 13:17:23
1081
原创 ASP.NET Coer Kestrel Web服务器配置终结点
从 .NET 7 的 Kestrel 中删除默认 HTTPS 地址和端口。的一部分,这将改善处理 HTTPS 时的整体开发人员体验。
2025-02-11 04:14:53
385
原创 ASP.NET Core程序的部署
不能直接把bin/Debug部署到生产环境的服务器上,性能低。应该创建网站的发布版,用【发布】功能。两种部署模式:“框架依赖”和“独立”。独立模式选择目标操作系统和CPU类型。Windows、Linux、iOS;关于龙芯。网站的运行在Windows(SandBox)和Linux(VMWare Player)里分别运行网站。如何在生产服务器中部署.NET Core网站。尽管Kestrel已经强大到足以作为一个独立的Web服务器被使用了,但是一般仍然不会让Kestrel直接面对终端用户的请求。配置域名
2025-02-11 00:06:34
464
原创 ASP.NET Core SignalR实践指南
Hub类的生命周期是瞬态的,每次调用集线器的时候都会创建一个新的Hub类实例,因此不要在Hub类中通过属性、成员变量等方式保存状态。如果服务器的压力比较大,建议把ASP.NET Core程序和SignalR服务器端部署到不同服务器上,以免它们互相干扰。如果需要在客户端连接到集线器或者在集线器断开的时候执行代码,我们可以覆盖Hub类中的OnConnectedAsync和OnDisconnectedAsync方法。SignalR除了提供了供浏览器使用的JavaScript客户端,官方还提供了.NET、Ja
2025-02-10 21:56:22
365
原创 ASP.NET Core SignalR案例:导入英汉词典
ImportExecutor中注入IHubContext等服务。暂时用字符串Split解析CSV,或者用更专业的库。用SqlBulkCopy 进行分批快速导入:
2025-02-10 21:41:22
351
原创 ASP.NET Core 外部向SignalR的Hub发消息
Hub类中的方法只应该用于消息的发布,而不应该用来写业务逻辑,SignalR中客户端给服务器端传递消息的超时时间为30s,如果对Hub类中的方法的调用执行时间超过30s,程序就会IHubContext接口和Hub类有区别,因此在IHubContext中不能调用Caller、Others等成员啊,所以不能向“当前连接的客户端”、“除了当前连接之外的其他客户端”推送消息。在控制器等集线器的外部调用的IHubContext服务,这些请求并不在一个SignalR连接中,因此也就没有“当前SignalR连接”的概念。
2025-02-10 02:01:09
397
原创 ASP.NET Core SignalR向部分客户端发消息
客户端筛选的3个参数:ConnectionId、组和用户Id(它对应ClaimTypes.NameIdentifier的Claim)。Hub的Groups属性为IGroupManager属性,可以对组成员进行管理。查看类型的成员。Hub的Clients属性为IHubCallerClients类型,可以对连接到当前集线器的客户端进行筛选。查看类型的成员。IClientProxy类型。无法知道具体有哪些客户端调用SendAsync()方法向筛选的客户端发送消息。实现聊天室私聊。
2025-02-10 01:01:45
821
原创 ASP.NET Core SignalR身份验证
在需要登录才能访问的集线器类上或者方法上添加[Authorize]。也支持角色等设置,可以设置到Hub或者方法上。配置好User、Role、MyDbContext、JWTSettings、IdentityHelper。
2025-02-09 20:56:39
332
原创 ASP.NET Core SignalR的分布式部署
假设聊天室程序被部署在两台服务器上,客户端1、2连接到了服务器A上的ChatRoomHub,客户端3、4连接到服务器B上的ChatRoomHub,那么客户端1发送群聊消息时,只有客户端1、2能够收到,客户端3、4收不到;在客户端3发送群聊消息,只有客户端3、4能够收到,客户端1、2收不到。AddStackExchangeRedis第一个参数为Redis服务器的连接字符串,如果有多个SignalR应用程序连接同一台Redis服务器,需要为每个应用程序配置唯一的ChannelPrefix。
2025-02-09 14:41:05
290
原创 ASP.NET Core SignalR的协议协商
SignalR支持多种服务器推送方式:Websocket、Server-Sent Events、长轮询。默认按顺序尝试。“粘性会话”(Sticky Session):把来自同一个客户端的请求都转发给同一台服务器上。缺点:因为共享公网IP等造成请求无法被平均的分配到服务器集群;扩容的自适应性不强。“禁用协商”:直接向服务器发出WebSocket请求。WebSocket连接一旦建立后,在客户端和服务器端直接就建立了持续的网络连接通道,在这个WebSocket连接中的后续往返WebSocket通信都是由同一台服
2025-02-09 14:25:52
321
原创 ASP.NET Core WebSocket、SignalR
ASP.NET Core SignalR(以下简称SignalR),是.NET Core平台下对WebSocket的封装。Hub(集线器),数据交换中心。WebSocket基于TCP协议,支持二进制通信,双工通信。性能和并发能力更强。WebSocket独立于HTTP协议,不过我们一般仍然把WebSocket服务器端部署到Web服务器上,因为可以借助HTTP协议完成初始的握手(可选),并且共享HTTP服务器的端口(主要)。
2025-02-09 02:45:02
996
原创 ASP.NET Core数据校验FluentValidation
FluentValidation.AspNetCore 包不再维护,现在不受支持。我们鼓励用户放弃此包,并使用具有手动验证方法的核心 FluentValidation 包,用类似于EF Core中Fluent API的方式进行校验规则的配置,也就是我们可以把对模型类的校验放到单独的校验类中。
2025-02-09 01:07:27
695
原创 ASP.NET Core托管服务
场景,代码运行在后台。比如服务器启动的时候在后台预先加载数据到缓存,每天凌晨3点把数据导出到备份数据库,每隔5秒钟在两张表之间同步一次数据。托管服务实现接口,一般编写从继承的类。
2025-02-08 17:03:07
434
原创 ASP.NET Core JWT Version
解决JWT无法提前撤回问题,每次登录、发放令牌的时候,都让JWTVersion的值自增,同时将JWTVersion的值也放到JWT令牌的负载中;当执行禁用用户、撤回用户的令牌等操作的时候,把这个用户对应的JWTVersion列的值自增;当服务器端收到客户端提交的JWT令牌后,先把JWT令牌中的JWTVersion值和数据库中JWTVersion的值做一下比较,如果JWT令牌中JWTVersion的值小于数据库中JWTVersion的值,就说明这个JWT令牌过期了。
2025-02-08 15:47:49
814
原创 ASP.NET Core将Bearer身份验证添加到Scalar
添加BearerSecuritySchemeTransformer类。自定义 OpenAPI 文档 | Microsoft Learn。修改Program.cs。
2025-02-08 13:06:03
451
原创 ASP.NET Core对JWT的封装
配置JWT节点,节点下创建SigningKey、ExpireSeconds两个配置项,分别代表JWT的密钥和过期时间(单位:秒)。再创建配置类JWTOptions,包含SigningKey、ExpireSeconds两个属性。Nuget:Microsoft.AspNetCore.Authentication.JwtBearer对JWT进行配置Program.cs的app.UseAuthorization()这行代码之前添加app.UseAuthentication()Controller类中进行登录
2025-02-07 01:03:42
1134
原创 ASP.NET Core JWT
JWT把登录信息(也称作令牌)保存在客户端。为了防止客户端的数据造假,保存在客户端的令牌经过了签名处理,而签名的密钥只有服务器端才知道,每次服务器端收到客户端提交过来的令牌的时候都要检查一下签名。
2025-02-06 16:31:17
500
原创 ASP.NET Core标识框架Identity
标识(Identity)框架:采用基于角色的访问控制(Role-Based Access Control,简称RBAC)策略,内置了对用户、角色等表的管理以及相关的接口,支持外部登录、2FA等。标识框架使用EF Core对数据库进行操作,因此标识框架支持几乎所有数据库。
2025-02-06 02:16:15
879
原创 Object.defineProperty与Vue数据代理
通过Object.defineProperty()把data对象中所有属性添加到vm上。在getter/setter内部去操作(读/写)data中对应的属性。为每一个添加到vm上的属性,都指定一个getter/setter。value,writable和get,set只能写一个。通过vm对象来代理data对象中属性的操作(读/写)通过一个对象代理对另一个对象中属性的操作(读/写)更加方便的操作data中的数据。
2025-02-04 02:23:42
138
原创 ASP.NET Core中Filter与Middleware的区别
中间件是ASP.NET Core这个基础提供的功能,而Filter是ASP.NET Core MVC中提供的功能。ASP.NET Core MVC是由MVC中间件提供的框架,而Filter属于MVC中间件提供的功能。
2025-02-04 01:24:33
349
原创 ASP.NET Core中间件Markdown转换器
需在app.UseStaticFiles();之前注册,如果先注册了静态文件中间件,那么所有对静态文件的请求都会直接由静态文件中间件处理,而不会经过你的自定义中间件。
2025-02-04 00:13:59
603
原创 ASP.NET Core中间件的概念及基本使用
中间件是ASP.NET Core的核心组件,MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。广义上来讲:Tomcat、WebLogic、Redis、IIS;狭义上来讲,ASP.NET Core中的中间件指ASP.NET Core中的一个组件。中间件由前逻辑、next、后逻辑3部分组成,前逻辑为第一段要执行的逻辑代码、next为指向下一个中间件的调用、后逻辑为从下一个中间件执行返回所执行的逻辑代码。
2025-02-03 16:23:17
751
原创 ASP.NET Core筛选器Filter
切面编程机制,在ASP.NET Core特定的位置执行我们自定义的代码。ASP.NET Core中的Filter的五种类型:Authorization filter、Resource filter、Action filter、Exception filter、Result filter。本书中重点讲解Exception filter和Action filter。所有筛选器一般有同步和异步两个版本,比如IActionFilter、IAsyncActionFilter接口。
2025-02-02 21:59:04
791
原创 ASP.NET Core与EF Core的集成
如果项目采用小上下文策略,在项目中可能就存在多个上下文类,需要手动调用AddDbContext方法注册,如果上下文连接的是同一个数据库,可以采用反射的方式扫描程序集中所有的上下文,然后为它们逐个调用AddDbContext注册。配置完环境变量需重启VS。DbContext名。DbContext名。
2025-02-02 19:46:18
1265
原创 ASP.NET Core与配置系统的集成
ASP.NET Core 会从环境变量中读取名字为ASPNETCORE_ENVIRONMENT的值。推荐值:Development(开发环境)、Staging(测试环境)、Production(生产环境)。
2025-02-01 14:51:27
556
原创 ASP.NET Core分布式缓存
分布式系统中,内存缓存不满足要求的话,把缓存数据保存到专门的缓存服务器,所有Web应用通过缓存服务器进行缓存数据的写入和获取。常用的分布式缓存服务器有Redis、Memcached等。.NET Core中提供了统一的分布式缓存服务器的操作接口IDistributedCache,用法和内存缓存类似。分布式缓存和内存缓存的区别:缓存值的类型为byte[],需要我们进行类型转换,也提供了一些按照string类型存取缓存值的扩展方法。用SQLServer做缓存性能并不好。
2025-02-01 02:37:44
614
原创 ASP.NET Core缓存穿透和缓存雪崩
对于大部分正常请求,客户端都会将信息保存到缓存中,后续从缓存读取,数据库压力小;但是针对在数据库不存在的数据,缓存中不会保存任何信息,如果恶意访问使用不存在id来发送大量请求,数据库压力大,可能会导致崩溃,这就叫。使用IMemoryCache接口中的Get和Set设置缓存时,首先从缓存中查询是否有缓存键对应的缓存内容,如果没有,则去数据库查,并把查询结果写入缓存。我们用GetOrCreateAsync方法即可,因为它会把null值也当成合法的缓存值。缓存项集中过期引起缓存雪崩。
2025-01-27 17:05:05
472
原创 ASP.NET Core缓存
无论用那种过期时间策略,程序中都会存在缓存数据不一致的情况。部分系统(博客等)无所谓,部分系统不能忍受(比如金融)。可以通过其他机制获取数据源改变的消息,再通过代码调用IMemoryCache的Set方法更新缓存。
2025-01-27 16:37:13
1730
原创 ASP.NET Core WebAPI的异步及返回值
使用[FromQuery]来获取QueryString中的值。如果名字一致,只要为参数添加[FromQuery]即可;而如果名字不一致,[FromQuery(Name = 名字)]。QueryString和Route可以混用。1、从Content-Type为multipart/form-data的请求中获取数据的[FromForm]2、从请求报文头中获取值的[FromHeader]。
2025-01-25 03:10:21
1068
原创 .NET9增强OpenAPI规范,不再内置swagger
ASP.NETCore in .NET 9.0 OpenAPI官方文档ASP.NET Core API 应用中的 OpenAPI 支持概述 | Microsoft Learn提取生成的 OpenAPI 文档时,文档名称作为请求中的参数提供。
2025-01-24 14:00:25
1241
原创 ASP.NET Core MVC
控制器由Controller类实现,视图一般是扩展名为cshtml的文件,而模型则是只有属性的普通C#类。控制器类的名字一般以Controller结尾,并且被放到Controllers文件夹下。控制器的名字为控制器的类名去掉Controller。视图一般被放到Views文件夹下的控制器名字的文件夹下。视图→浏览器端提交的请求→模型→控制器→处理→模型→视图。渲染:Render。
2025-01-24 03:04:40
947
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人