.NET Core MVC扩展实践

源宝导读:明源云ERP的底层架构正在向.Net Core跨平台迁移,我们在过程中遇到了部分不兼容的问题。本文将介绍技术团队如何解决.Net Core与已有MVC框架不兼容问题的解决方案。

一、背景

    云ERP的建模平台是基于.NET Framework构建的,在向.NET Core迁移的过程中会遇到各种问题,向下兼容是一定要考虑的,框架本身的特性兼容交给微软,但是还有很多的特性可能是旧版建模平台需要支持的特性,比如多参数绑定、服务工厂Controller激活。今天就聊聊在向.NET Core迁移时如何兼容以上两个特性。

二、概念解释

  • 服务工厂

    • 云ERP的服务工厂是建模平台的内部服务管理实现,用于创建ERP各个领域服务类实例,在创建服务对象的过程中会进行加工,根据二开模式(Before/After/Override)动态创建携带插件方法的代理类型,以达到易二开的技术特性。

  • 应用服务

    • 应用服务是云ERP的入口,它们是由一系列后缀名为AppService的Class组成的,概念上相当于MVC的Controller,作用也一样。

  • 自定义路由

    • 云ERP的路由中添加了命名空间地址,官方的模板格式无法满足,本文利用ControllerModelConvention在Apply时为每一个Action批量配置路由。路由格式: `api/ {controller.ControllerType.FullName} /{action.ActionName}.aspx`

  • Controller激活

    • 云ERP也是基于MVC构建的,Controller也是服务,也是需要可扩展,自然需要通过服务工厂去创建,这就需要找到.NET Core MVC中Controller激活的时机,使用服务工厂创建替换掉默认的类实例化过程。

  • 多参数绑定

    • .NET Core MVC 中天生是不支持将[FromBody]数据源绑定到Action的多个参数上的。这一特性在微软官方文档中有解释(参考:微软对FromBody的参数绑定限制说明)。由于这个限制,我们必须在向.NET Core MVC迁移时尝试解决这个问题,思路与Controller激活的差不多,就是找到参数绑定的默认实现,替换掉它。

为了大家能统一语言,请提前了解下.NET Core MVC的基本特性,这里就不再阐述,需要了解的读者请点击传送门。

三、面临的问题

让MVC路由到云ERP的AppService

    .NET Framework MVC 升级到 .NET Core MVC 在实现原理上有很大不同,由服务管线变成了中间件管道,无法直接使用HttpHandler实现了,必须重新实现Controller路由到激活的过程。

    那么将面临两个问题:

  1. 自定义路由,首先要能让MVC认知AppService并能按照云ERP的模板规范进行路由。

  2. 路由到AppService后激活的方式得用服务工厂 ServiceFactory来创建,这样才能兼容二开的插件模式。(注:服务工厂中创建的是AppService的代理类的实例,携带二开定义的插件方法)

支撑多参数绑定

   云ERP多参数绑定的解决方案是利用的ClownFish.net框架中的  ClownFish. Web.Serializer. JsonnetDataProvider 来解决的(ClownFish.net明源云的架构师FishLi多年前的作品,已在Github上开源)。

    迁移到.NET Core MVC中就需要自己实现了,原理差不多,这里不多讲有兴趣的可以看源码。

四、解决思路

要在.NETCore MVC中兼容云ERP的MVC特性,核心要解决的就是以下三点:

  1. 自定义路由。

  2. controller激活。

  3. 多参数绑定。

我们一个一个来解决。

自定义路由

    首先我们得让MVC认识AppService,不然无法做后面的事情。创建一个 AppServiceFeatureProvider 继承 ControllerFeatureProvider 用来将AppService提供给MVC框架作为控制器使用。并且将AppServiceFeatureProvider提供程序加入MVC的特性提供者集合中。最后在 ConfigureServices 中调用 AddClownFish()。

    接下来,就是要给每一个AppService的方法(Action)设置自定义路由。这里利用的是.NET Core MVC的一个Convention 特性,不了解的读者先阅读一下微软文档。

(https://docs.microsoft.com/zh-cn/aspnet/core/mvc/controllers/application-model?view=aspnetcore-3.0#conventions)。

    创建一个 AppServiceModelConvention 类型 实现 IControllerModelConvention的Apply 接口。为ControllerModel的每一个Action创建属性路由(AttributeRouteModel),代码如下,为了保证理解容易,我隐藏了部分不重要的代码,文末有Demo源代码链接可以下载。在AddClownFish扩展方法中把AppServiceModelConvention加如MVC的约定列表。

Controller激活

所以分解任务就是:

  1. 创建 ClownFishControllerActivator 替换默认的Controller激活器实现

  2. 实现ERP自定义的激活器,用服务工厂创建AppService实例

  3. 把ClownFishControllerActivator加入服务列表中

代码比较简单:

    这里值得一提的是,微软在MVC框架中确实实现了一个默认的激活器实现,但是如果你不去主动使用它,默认他是不使用的,会跳过。避免被坑,我截图说明了一下:

多参数绑定

    多参数绑定实现起来比较费劲,主要是因为参数绑定的过程是封闭的,这里利用了篡改缓存的实现,用自定义的Lambad表达式构建了一个新的实例来替换掉默认的实现。

思路:

  1. 实现 IActionInvokerProvider 替换掉默认实现。

  2. 在Action执行时构建一个自定义的Bind函数替换掉缓存中的Bind函数,返回一个新的缓存对象。

  3. 自定义的Bind函数中就可以拿到HttpContext了,这样就可以为所欲为了,自己创建一个JsonTextReader来自由读取Body然后依次绑定到Controller的arguments列表中。

  4. 然后把新的缓存对象塞回缓存字典中。

代码如下:

四、总结

    阅读官方文档发现 .NET Core MVC提供了丰富的扩展机制,这为上层框架的发展提供了可能,通过阅读MVC源码可以学习微软程序员的代码设计思想,思考并提炼应用到ERP的产品代码设计中,这也是开源的一种福利吧。

最后附上Demo源码地址:

https://github.com/zongzijie/study/tree/master/CSharp/SampleForAspNetCoreMvc

------ END ------

作者简介

伍同学: 研发工程师,目前负责售楼系统的相关设计开发工作。

也许您还想看

ERP缓存实践经验分享

.Net最小工作线程对应用程序性能的影响

记一次生产环境CPU100%排查实践

如何使用有序GUID提升数据库读写性能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab title多个标题_MATLAB中的直方图处理及均衡化

直方图是多种空间域处理技术的基础。仿图操作能有效地用于图像增强,直方图固有的信息在其他图像处理应用中也是非常有用的,如图像压缩与分割。訪图在软件中易于计算,也适用于商用硬件设备,因此直方图成为实时图像处理的一个流行工…

成本计算引擎动态规则解析技术详解

源宝导读:随着企业数字系统应用的越来越深入,业务计算方式也变的越来越复杂,灵活度要求也越来越高。本文将介绍通过将配置动态转换成可执行代码的方式,解决业务计算高度灵活化配置的技术方案。一、背景ERP本质上是一种“业务密集型…

Kubernetes,多云和低代码数据科学:2020年最热门的数据管理趋势

新兴技术为我们的数据之旅铺平了道路。我们已经看到Kubernetes在应用程序自动化方面处于领先地位,越来越多的公司将赌注押在了云上,以及当今的企业对数据科学的依赖程度正不断提,再加上对大数据的人工智能高级分析,可以看到数据管…

matlab光盘映像文件可以删除吗_DVD-Cloner 2020 for mac(DVD光盘刻录工具) 7.00.715

DVD-Cloner Gold 2020版是功能强大的DVD光盘刻录工具,DVD-Cloner Gold 2020版可以轻松刻录光盘以及蓝光光盘,用户可以将任何的文件刻录到DVD光盘中,并可以制作为蓝光光盘,可以很方便地录入视频到光盘中进行保存,刻录好…

性能优化 = 改改代码?

大家好,我是Z哥。好久没写技术文章了,最近正好有进行一些思考,顺手写出来分享给大家。如果不是程序员的话,可以快速扫一眼正文的几个小标题,快速略过即可,毕竟思路和专业无关,很多是相通的。&am…

使用refs获取节点_闲庭信步聊前端 - 原来你是这样的Refs

一、refs 的由来什么是refsrefs是拿到真实的DOM节点和React元素实例的一种方法。在React官方文档中有提到Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。 React是单向的数据流,父子组件的交互是通过props。修改子组件…

从TimeSpan说起

小编在编写WPF程序时,需要做一个判断:定时使用Modbus协议使用Quartz.net 定时任务读取设备中的数据,同时也使用定时任务判断是否长时间获取不到数据的情况,如果程序中超过一分钟没有获取到数据(数据没有更新&#xff0…

如何维持手机电池寿命_延长手机电池寿命终极技巧教学,iPhone和安卓手机皆适合...

每隔一阵子就开始有不少用户询问,iPhone电池健康度又剩下多少了,怎么朋友的还维持在100%,是不是我手机电池出问题,引起不少用户翻白眼。会有电池健康度,最主要是要让大家了解目前手机电池当前寿命,只要电池…

2020年了,再不会Https就老了

合格的web后端程序员,除搬砖技能,还必须会给各种web服务器启用Https,本文结合ASP.NET Core部署模型聊一聊启用Https的方式。温故知新目前常见的Http请求明文传输,请求可能被篡改,访问的站点可能被伪造。HTTPS是HTTP加上…

c语言枚举类型例题_[开源资讯]Zig 0.6.0 发布,想要挑战 C 语言

Zig 0.6.0 已发布,这是一门通用编程语言,专为稳定性、可维护性和性能而设计,追求替代 C 语言在系统编程上的最佳地位。Zig 具有以下值得关注的特性:手动管理内存与 C 语言竞争而非依赖它,Zig 标准库不依赖于 libc轻量而…

【实战 Ids4】║ 给授权服务器加个锁——HTTPS配置

在上篇文章《【实战 Ids4】║客户端、服务端、授权中心全线打通!》中,我们正式的将三站打通,发布过后,有小伙伴反馈,可能Nginx对配置HTTPS安全协议有点儿问题,我也就半夜趁着没人打扰,疯狂的研究…

快速幂 a*b%c

2020.12.30开始学习AcWing算法《算法竞赛进阶指南》&#xff1b; 在CSDN上传博客方便复习。 //wecccccccc //2020.12.30 #include <iostream> using namespace std; typedef long long int ll;ll fast_power(ll a, ll b, ll c) {ll ans 1;a % c;//防止一开始输入的值过…

thinkphp 助手函数url不生成https_如何用ThinkPHP框架写一个快递查询接口

ThinkPHP是php程序员们经常使用的框架之一&#xff0c;运用框架来开发网站无疑减轻了我们代码量&#xff0c;加快了我们的开发速度&#xff0c;框架底层封装的方法和函数使用起来简直不能太爽。今天给大家总结一个小案例&#xff0c;如何实现一个快递查询的接口。所谓接口&…

64位整数乘法

2020.12.30开始学习AcWing算法《算法竞赛进阶指南》&#xff1b; 上传博客方便复习。 //Wecccccccc //2020.12.30 #include <iostream> using namespace std; typedef unsigned long long int ull;int main() {ull a, b, c;cin >> a >> b >> c;ull ans…

分布式锁的实现与探索

源宝导读&#xff1a;大型的信息化系统对数据准确性的要求很高&#xff0c;所以经常会使用事务、锁、队列等技术&#xff0c;保障高并发下的数据一致性问题。本文将讨论在分布式部署模式下&#xff0c;如何利用锁机制保证业务数据准确的技术探索与实践。一、背景分布式场景下的…

matlab 角度转四元数_基于Matlab的机械臂路径规划

什么是 trajectory(路径)规划中文路径在英语中可能有两种翻译&#xff1a;1. path2. trajectory首先告诉大家&#xff0c;我们所说的“路径”是后者——trajectory。我们看一下这两种“路径”在机械臂的世界里有什么区别。设想机械臂的 end-effector 要从 A 点运动到 B 点&…

ASP.NET Core 中间件的几种实现方式

前言ASP.NET Core 中 HTTP 管道使用中间件组合处理的方式,换句人话来说,对于写代码的人而言,一切皆中间件.业务逻辑/数据访问/等等一切都需要以中间件的方式来呈现.那么我们必须学会如何实现自定义中间件 这里划重点,必考这里我们介绍下中间件的几种实现方式...匿名函数通常新建…

cookies默认过期时间_「图」Chrome Canary新版已启动“增强版cookies控制”预览测试...

近日谷歌承诺将于今年晚些时候在Chrome浏览器启动“增强版cookies控制”的预览测试。在今年的I/O开发者大会上&#xff0c;谷歌宣布携手Mozilla等开发者耗时3年多时间制定了名为“same-site cookies”的IETF 标准&#xff0c;而该功能就是建立在same-site cookies的基础上&…

【原创】StackOverflow 20万关注的问题:如何实现异步Task超时的处理?

前文传送门 dotNET开发系列收藏&#xff01;推荐12个超实用的Visual Studio插件程序员&#xff1a;这10种糟糕的程序命名&#xff0c;你遇到过几个&#xff1f;使用Vistual Studio N年&#xff0c;推荐2个异常捕获的技巧面试官&#xff1a;你连RESTful都不知道我怎么敢要你&…

C# WPF 表单更改提示

微信公众号&#xff1a;Dotnet9&#xff0c;网站&#xff1a;Dotnet9&#xff0c;问题或建议&#xff0c;请网站留言&#xff1b; 如果您觉得Dotnet9对您有帮助&#xff0c;欢迎赞赏Dotnet9.com内容目录实现效果业务场景编码实现本文参考源码下载1.实现效果未做修改的表单展示 …