
.NET
文章平均质量分 87
.NET 是一个免费的开放源代码项目
用于构建所有应用(Web 应用、移动应用、桌面应用、游戏、IoT 等)的开发人员平台。 在 Windows、Linux 和 macOS 上受支持。
林晓lx
登高现红日,实践出真知!
展开
-
开箱即用的.NET MAUI组件库 V-Control 发布了!
之前写过挺多的MAUI Sample,其中有很多代码可以打包成组件,当组件完善到一定程度,我会把控件封装起来放到控件库中。今天,在这个仓库建立一年零八个月后,我觉得可以考虑将其作为开源库发布。有很多网友在观望.NET MAUI,犹豫是否可以拿来作为有生产力的跨平台移动端开发工具,此时我想告诉大家,.NET MAUI是一个非常不错的移动开发平台。配合 V-Control 来构建移动应用程序,V-Control是适用于。原创 2025-02-06 18:00:47 · 1374 阅读 · 0 评论 -
[MAUI]集成富文本编辑器Editor.js至.NET MAUI Blazor项目
其它的工具插件可以单独获取。在OnAfterRenderAsync中调用初始化函数,并订阅OnSubmitting和OnInited事件,以便在提交事件触发时保存,以及文本状态变更时重新渲染。在wwwroot创建editorjs_index.html文件,并在body中引入editorjs.umd.js和各插件js文件。我们先要获取web应用的资源文件(js,css等),以便MAUI的视图呈现标准的Web UI。在script代码段中,创建LoadContent函数,用于加载EditorJs的初始内容。原创 2024-04-13 23:47:05 · 1206 阅读 · 2 评论 -
[.NET项目实战] Elsa开源工作流组件应用(三):实战演练
之前的文章简单介绍了工作流和Elsa工作流库,这里再补充说明两点工作流的使用场景非常广泛,几乎涵盖了所有需要进行业务流程自动化管理的领域。学习一个开源库,最简单的方法就是看源码,Elsa的工作流引擎源码非常简单易懂,并且提供了非常丰富的示例代码,举一个例子:审批工作流示例这个审批流是这样的:作者发来一个文章,有两个审批人需要全部审批通过,文章才算通过,否则退回。原创 2024-03-20 18:32:22 · 2209 阅读 · 6 评论 -
[.NET项目实战] Elsa开源工作流组件应用(二):内核解读
Elsa工作原理可以抽象理解为管道中间件 + 异步模型Elsa中,活动的变量的获取和设置都是异步的。Elsa定义了Variable类型作为异步操作的结果或者说是异步操作的占位符,这个变量在运行的时候才会填充数值。这与我们熟悉C#中的Task,或者js里的promise对象作用相同。输入Input,OutPut都属于 Variable。Elsa模拟了内存寄存器(MemoryRegister)以及Set和Get访问器实现异步模型。原创 2024-03-20 11:47:07 · 2530 阅读 · 0 评论 -
[.NET项目实战] Elsa开源工作流组件应用(一): Elsa工作流简介
工作流定义描述了一个工作流的结构,比如:名称,变量,包含的活动等,可以理解为一个工作流的模板。工作流定义在Elsa初始化时会“注册” 到资源池中,每个工作流定义都有一个唯一的ID。使用设计器生成的工作流,通过序列化成JSON字符串,并持久化到数据库。使用硬编码创建的工作流,在Elsa初始化时将工作流注册到工作流定义并持久化到数据库。实例化是根据定义创建一个工作流的实例,工作流实例包含工作流状态(WorkflowState)以及活动实例(ActivityState)。原创 2024-03-15 17:16:27 · 3230 阅读 · 0 评论 -
将Abp默认事件总线改造为分布式事件总线
定义NotificationEventData,用于传递自定义事件。set;set;set;set;在消费者端,定义一个事件处理器,用于处理自定义事件。在生产者端,触发自定义事件。运行程序,可以看到消费者端打印出了自定义事件。原创 2023-12-20 17:06:27 · 1914 阅读 · 0 评论 -
将ECharts图表插入到Word文档中
首先指定一个option,在官方示例 https://echarts.apache.org/examples/zh/index.html 中,随意找一个柱状图的sample,复制option对象内容到新创建的option.json文件中。echarts-convert在github上有众多版本,echarts-convert的代码来源于这里:https://github.com/wadezhan/billfeller.github.io/issues/85。将下载好的可执行文件解压放置在项目根目录下的。原创 2023-11-15 11:24:23 · 1244 阅读 · 0 评论 -
DocTemplateTool - 可根据模板生成word或pdf文件的工具
你是否经常遇到这样的场景:产品运营有着大量的报告需求,或者给客户领导展现每周的运营报告?这些文档类的任务可以交给运营同事,他们负责文档排版和样式,你作为开发人员你只需要提供数据源,和一个映射表,告诉制作文档的人哪些字段可供使用。这样一来分工明确,减少了很多不必要的沟通成本。原创 2023-11-07 19:03:50 · 1464 阅读 · 0 评论 -
ExcelPatternTool 开箱即用的Excel工具包现已发布!
应用系统开发中少不了跟Excel打交道,基于NPOI开发了ExcelPatternTool,与目前主流框架对比ExcelPatternTool着重单元格样式的控制,对于初始数据导入、报表导出等简单的Excel功能提升易用性。原创 2023-10-25 18:23:11 · 789 阅读 · 0 评论 -
[MAUI]深入了解.NET MAUI Blazor与Vue的混合开发
每个BlazorWebView控件包含根组件(RootComponent)定义,ComponentType是在应用程序启动时加载页面时的类型,该类型需要继承自Microsoft.AspNetCore.Components.IComponent,由于我们的导航是由MAUI处理的,因此我们不需要使用Blazor路由,直接使用Razor组件。开发应用需要一个独立的host项目。中引入,还有一种是使用并置的js文件,这种方式是所谓的"CodeBehind",因为更利于组织代码,这里我们使用并置的js文件。原创 2023-10-18 17:12:29 · 2462 阅读 · 4 评论 -
[MAUI]实现动态拖拽排序网格
拖拽控件悬停在当前控件上方时,将IsBeingDraggedOver设置为true,通知当前控件正在有拖拽控件悬停在其上方,同时在服务列表中寻找当前正在被拖拽的服务,将DropPlaceHolderItem设置为当前控件。当以比较快的速度,拖拽Tile经过较多的位置时,后面的Tile会短暂地替代原先的位置,导致拖拽中的Tile不在期望的Tile上方,而拖拽中的Tile与错误的Tile产生了交叠从而触发DraggedOver事件,导致错乱。其是在松开手指之后才向列表提交条目位置变更的命令。原创 2023-09-18 17:55:05 · 524 阅读 · 0 评论 -
在Volo.Abp微服务中使用SignalR
假设需要通过Signalr发送消息通知,并在前端接收消息通知的功能。原创 2023-08-03 11:21:04 · 1687 阅读 · 0 评论 -
怎样优雅地增删查改(九):按日期范围查询
使用数据库的创建时间作为查询依据,在Abp框架中,实体类实现ICreationAuditedObject接口,或继承CreationAuditedEntity类,使用仓储创建记录时将自动生成CreationTime。原创 2023-07-21 16:14:42 · 213 阅读 · 0 评论 -
利用Abp过滤器实现业务数据“回收站”功能
利用这个原理,可以将“软删除”行为认为是放入了“回收站”,而将“恢复”行为认为是从“回收站”中取出。将记录硬删除的行为认为是“永久删除”, 将全部已“软删除”的记录硬删除,则是“清空回收站”在DbContext中,重写CreateFilterExpression方法,当启用了“仅查看软删除”过滤器时,自动过滤软删除的实体。在删除记录时,通过调用仓储的Delete()方法,将记录放入“回收站”中。回收站是当用户删除一条记录时,不是直接从数据库中删除,而是将其放入“回收站”,以便用户可以在需要时恢复数据。原创 2023-07-19 10:06:01 · 363 阅读 · 0 评论 -
怎样优雅地增删查改(八):按用户关系查询
查询目标业务对象HealthAlarm关联了业务用户HealthClient,因业务用户与鉴权用户IdentityUser共享同一个Id,因此可以通过查询用户关系关联的User,查询到业务对象。对于Relation服务,其依赖关系在应用层,查找指定用户的关系用户将在CurdAppServiceBase的子类实现。对于Relation服务,其依赖关系在应用层,查找指定用户的关系用户将在CurdAppServiceBase的子类实现。人员之间的关系是单项的,也就是说可以A是B的好友,但B不一定是A的好友。原创 2023-07-18 14:50:43 · 196 阅读 · 0 评论 -
怎样优雅地增删查改(七):按用户查询
若指定 UserId 为 Guid.Empty,则使用当前登录用户的 UserId。查询实体列表Dto若实现该接口,将筛选指定 UserId 下的关联的实体。ICurrentUser是Abp的一个服务,用于获取当前登录用户的信息。打开客户详情页面,点击“告警”标签页,可以看到该客户下的告警列表。告警创建完成后,进入客户管理,在右侧客户列表中点击“查看详情”在告警管理页面中,创建一些告警,并将这些告警分配给不同的客户。在不同“群组”下创建一些客户(Client)创建一些组织架构,命名“群组”原创 2023-07-18 10:36:35 · 196 阅读 · 0 评论 -
怎样优雅地增删查改(六):按任意字段关键字查询
定义按任意字段关键字查询过滤器(IKeywordOrientedFilter)接口,查询实体列表Dto若实现该接口,将筛选指定的目标字段(TargetFields)包含指定的关键字(Keyword)的实体。对于每一个TargetField,需要在实体中找到对应字段(属性)。若找到,则为此实体字段创建条件筛选的表达式,然后将这些表达式通过Or连接起来,最终返回一个包含多段关键字筛选的Lambda表达式。可以看到将筛选出标题包含关键字“3”的告警。在筛选中输入关键字“3”,点击查询。无需在应用层中更改代码,原创 2023-07-13 20:35:10 · 263 阅读 · 0 评论 -
怎样优雅地增删查改(五):按组织架构查询
要想在任意实体实现Where的过滤条件,我们使用动态拼接语言集成查询 (LINQ) 的方式实现通用查询接口,有关LINQ表达式,请阅读。定义按组织架构查询过滤器(IOrganizationOrientedFilter)接口,查询实体列表Dto若实现该接口,将筛选指定 OrganizationUnitId 下的用户关联的实体。Employee的集合查询业务,是通过重写CreateFilteredQueryAsync方法,来实现按组织架构查询的过滤条件。创建一些组织架构,命名“群组”原创 2023-07-13 11:08:03 · 3298 阅读 · 0 评论 -
怎样优雅地增删查改(四):创建通用查询基类
上一章我们实现了Employee管理模块,Employee的增删改查是通过其应用服务类,继承自Abp.Application.Services.CrudAppService实现的。在开发业务模块时,我们可以先使用简单的方式提供Curd服务,随着UI复杂度增加,逐步的使用更加复杂的Curd服务。为了更好的代码重用,我们对泛型参数进行扩展,使用CurdAppServiceBase的类可根据实际业务需求选择泛型参数。Brief是一种简化的查询实体集合的方法,其返回的Dto不包含导航属性,以减少数据传输量。原创 2023-07-13 10:43:42 · 308 阅读 · 0 评论 -
怎样优雅地增删查改(三):业务用户的增删查改
区别于身份管理模块(Identity模块)的鉴权用户IdentityUser,业务用户(BusinessUser)是围绕业务系统中“用户”这一定义的领域模型。这些业务用户继承自HealthUser,HealthUser是业务用户的基类,包含了业务用户的基本信息,如姓名,性别,出生日期,身份证号等。以Client为例,ClientLookupService是业务用户的查询服务,其基类UserLookupService定义了关联用户的查询接口,包括按ID查询,按用户名查询,按组织架构查询,按户关系查询等。原创 2023-07-10 11:07:43 · 607 阅读 · 0 评论 -
怎样优雅地增删查改(二):扩展身份管理模块
人员之间的关系是单项的,也就是说可以A是B的好友,但B不一定是A的好友。组织(OrganizationUnit)是身份管理模块的核心概念,组织是树形结构,组织之间存在父子关系。Abp为我们实现了一套身份管理模块,此模块包含用户管理、角色管理、组织管理、权限管理等功能。增加人员与组织架构管理接口,如添加/删除人员到组织架构,查询组织架构下的人员,查询未分配组织的人员等;身份管理模块(Identity模块)为通用查询接口的按组织架构查询和按户关系查询提供查询依据。原创 2023-07-07 18:58:04 · 928 阅读 · 0 评论 -
Vue + Volo.Abp 实现OAuth2.0客户端授权模式认证
只需要清除vuex或Cookies中的token即可,可以调用vue-oidc-client的signOut,但只是跳转到配置的登出地址,不会清除token(前提是redirectAfterSignout为true,并设置了post_logout_redirect_uri)创建continue/index.vue,简单的显示登录成功的提示,常用的提示有“登录成功,正在为您继续”,“登录成功,正在为您跳转”等友好提示。(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。原创 2023-07-07 11:30:14 · 2141 阅读 · 0 评论 -
怎样优雅地增删查改(一):从0开始搭建Volo.Abp项目
软件系统中数据库或者持久层的基本操作功能可以用Curd描述,Curd即 增加(Create)、更新(Update)、读取查询(Retrieve)和删除(Delete), 这4个单词的首字母。在常见的业务系统中,对数据的大部分操作都是Curd,在实践的过程中对数据的筛选、排序、分页、关联查询等功能抽象和封装。本系列博文将从0开始,逐步搭建一个基于Volo.Abp + Vue 的前后端分离的,具有Curd通用查询功能的项目。项目介绍本项目是基于一个简单的用户健康数据管理系统,我们将对业务常用的查询功能进原创 2023-07-04 19:00:09 · 1426 阅读 · 0 评论 -
Volo.Abp升级小记(二)创建全新微服务模块
假设有一个按照搭建的微服务项目,并安装好了abp-cli。需要创建一个名为GDMK.CAH.Common的模块,并在模块中创建标签管理功能。原创 2023-06-09 14:37:37 · 2264 阅读 · 0 评论 -
[学习笔记]解决因C#8.0的语言特性导致EFCore实体类型映射的错误
今天下午在排查一个EF问题时,遇到了个很隐蔽的坑,特此记录。原创 2023-05-18 19:04:15 · 768 阅读 · 0 评论 -
Abp框架Web站点的安全性提升
本文将从GB/T 28448-2019《信息安全技术 网络安全等级保护测评要求》规定的安全计算环境中解读、摘要若干安全要求,结合Abp框架,对站点进行安全升级。原创 2023-04-18 10:32:33 · 457 阅读 · 0 评论 -
[Asp.Net Core] 网站中的XSS跨站脚本攻击和防范
跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Web脚本代码(html、javascript、css等),当用户浏览该页面时,嵌入其中的Web脚本代码会被执行,从而达到恶意攻击用户的特殊目的。源代码出自:https://www.cnblogs.com/OleRookie/p/5970167.html。重新访问,成功触发了XSS弹窗。原创 2023-04-14 18:38:30 · 439 阅读 · 0 评论 -
用Abp实现找回密码和密码强制过期策略
用户找回密码,确切地说是,为了保证用户账号安全,原始密码将不再以明文的方式找回,而是通过短信或者邮件的方式发送一个随机的重置校验码(带校验码的页面连接),用户点击该链接,跳转到重置密码页面,输入新的密码。这个重置校验码是一次性的,用户重置密码后立即失效。用户找回密码是在用户没有登录时进行的,因此需要先校验身份(除用户名+密码外的第二种身份验证方式)。第二种身份验证的前提是绑定了手机号或者邮箱,如果没有绑定,那么只能通过管理员进行原始密码重置。原创 2023-04-14 11:07:32 · 1063 阅读 · 0 评论 -
用Abp实现两步验证(Two-Factor Authentication,2FA)登录(三):免登录验证
常用的实现方式是在用户登录成功后,生成一个随机的字符串Token,将此Token保存在用户浏览器的 cookie 中,同时将这个字符串保存在用户的数据库中。当用户再次访问时,如果 cookie 中的字符串和数据库中的字符串相同,则免登录验证通过。rememberClientToken是存储于cookie中的,当用户登出时不需要清空cookie中的rememberClientToken,以便下次登录跳过两步验证。为了安全,Token采用对称加密传输存储,同时参与校验的还有用户Id,以进一步验证数据一致性。原创 2023-04-12 12:09:16 · 1911 阅读 · 0 评论 -
用Abp实现两步验证(Two-Factor Authentication,2FA)登录(一):认证模块
创建方法IsTwoFactorAuthRequiredAsync,返回登录用户是否需要双因素认证,若未开启TwoFactorLogin.IsEnabled、用户未开启双因素认证,或没有添加验证提供者,则跳过双因素认证。双因素认证(Two-Factor Authentication,简称 2FA)是使用两个或多个因素的任意组合来验证用户身份,例如用户提供密码后,还要提供短消息发送的验证码,以证明用户确实拥有该手机。至此,双因素认证的后端逻辑已经完成,接下来我们将补充“记住”功能,实现一段时间内免验证。原创 2023-04-07 18:31:07 · 1930 阅读 · 0 评论 -
解决Abp设置DefaultLanguage默认语言不生效的问题
默认地,Abp的语言提供程序将返回的CultureInfo为En,在一些默认实现的接口(比如/api/TokenAuth/Authenticate)返回的错误信息是英文。当请求到来时,会按照顺序依次调用这些语言提供程序,直到有语言提供程序的规则命中并返回了CultureInfo,这个CultureInfo就会被用于当前请求的语言设置。因此我们需要把AbpSettings中获取默认语言设置的优先级提高,即将AbpDefaultRequestCultureProvider排在默认的提供程序之前。原创 2023-04-04 14:14:21 · 1133 阅读 · 0 评论 -
[Volo.Abp升级笔记]使用旧版Api规则替换RESTful Api以兼容老程序
Volo.Abp 配置应用层自动生成Controller,增删查改服务(CrudAppService)将会以RESTful Api的方式生成对应的接口),这与旧版本的Abp区别很大。RESTful固然好,虽然项目里新的Api会逐步使用RESTful Api代替旧的,但在前后端分离的项目中已经定好的接口,往往需要兼容之前的方式。原创 2023-03-24 19:37:14 · 667 阅读 · 0 评论 -
探究C# dynamic动态类型本质
本周在做接口动态传参的时候思考了个问题:如何把一个json字符串,转成C#动态类?比如由生成解决这个问题前,我们先来了解一下dynamic动态类型。原创 2023-03-17 19:26:05 · 1814 阅读 · 2 评论 -
集成RocketChat至现有的.Net项目中,为ChatGPT铺路
今天我们来聊一聊一个Paas的方案,如何集成到一个既有的项目中。以其中一个需求为例子:在产品项目中,加入IM(即时通信)功能,开始徒手撸代码,会发现工作量很大,去github找开源项目,结果也可能事与愿违:功能不够强大,或者用不同的语言编写的,编译出来程序集无法集成到项目中。可能当下最好的方案是利用独立的聊天功能组件,作为项目的中间件(Paas方案)。组件是独立部署,独立运行的,功能的稳定性,搭建速度快,作为基础设施服务,可以用在其他项目中,并且项目中的对接作为抽象层,可随时替换现有组件。原创 2023-03-01 16:41:18 · 4124 阅读 · 3 评论 -
[MAUI 项目实战] 音乐播放器(三):界面交互
UI设计的本质是对于产品的理解在界面中多种形式的映射,当需求和定位不同时,对相同的功能表达出了不同的界面和交互方式。作为播放器,界面可以是千差万别的。《番茄播放器》的iOS平台上我开发了传统版本,和基于手势播放的版本。它们界面不同,但用的同一个播放内核。作为播放内核项目,在MatoMusic.Core的工作已经结束。本系列博文重点还是在播放器思路的解读,关于MAUI动画交互,我打算有时间另外写博客(这里给自己挖个坑)。原创 2023-02-27 00:23:51 · 1719 阅读 · 1 评论 -
[MAUI 项目实战] 音乐播放器(二):播放内核
曲目排序,原理是通过交换位置实现的,iOS和Android平台都有自己的可排序列表控件,在对选中的条目进行排序(往往是提起条目-拖拽-释放)的过程中,触发事件往往提供当前条目。在传统播放器随机播放时,如果下一曲不是我想听的,我仍然想听上一曲,由于上一曲按钮是随机触发的时机,你可能找不到它了,不得不再音乐列表再搜索它。播放控制类,用于当前平台播放器对象的操作,对当前所播放曲目的暂停/播放,下一首/上一首,快进快退(寻迹),随机、单曲模式等功能的控制。同样,用到了排序逻辑,再将他的排序(原创 2023-02-11 19:13:23 · 2068 阅读 · 2 评论 -
[MAUI 项目实战] 音乐播放器(一):概述与架构
为什么想起来这个项目了呢?这是一个Windows Phone 8的老项目,2014年用作为兴趣写了个叫“番茄播放器”的App,顺便提高编程技能。这个项目的架构历经多次迁移,从WP8到UWP再到Xamarin.Forms。去年底随着MAUI的正式发布,又尝试把它迁移到MAUI上来。原创 2023-02-11 18:59:51 · 5297 阅读 · 8 评论 -
适用于AbpBoilerplate的RocketChat Api库
适用于AbpBoilerplate的RocketChat Api库Rocket.Chat 是一个免费、开源、可扩展、高度可定制且安全的平台,可让您与团队进行交流和协作、共享文件和实时聊天(https://www.rocket.chat/)Rocket.Chat服务的安装请阅读。原创 2022-12-16 14:30:17 · 673 阅读 · 0 评论 -
用Abp实现短信验证码免密登录(二):改造Abp默认实现
接下来我们重写原Abp的部分实现,来驳接手机号相关业务。原创 2022-10-28 18:17:00 · 1436 阅读 · 0 评论 -
用Abp实现短信验证码免密登录(一):短信校验模块
这是一篇系列博文,我将使用Abp.Zero搭建一套集成手机号免密登录验证与号码绑定功能的用户系统:第三方身份验证在Abp中称之为, 区别于Abp的,这里Auth的全称应为Authorization,即授权。首先来厘清这两个不同的业务在Abp中的实现,我之前写的这篇系列文章中描述的业务,即使用的Abp外部身份授权(ExternalAuth)的相关扩展而实现的。还记得我们实现的WeChatAuthProvider吗?它继承于ExternalAuthProviderApi这个抽象类,实现的微信授权功能。原创 2022-10-28 17:57:50 · 1481 阅读 · 0 评论