ASP.NET Core是微软新推出支持跨平台、高性能、开源的开发框架,相比起原有的ASP.NET来讲,ASP.NET Core更适合开发现代应用程序,如跨平台、Dorker的支持、集成现代前端开发框架(如npm、bower、gulp等等)。另外相比ASP.NET它的性能更好,还内置了依赖注入等功能对开发方式进行了优化。但它们之间也有不少相同或类似的地方,如都使用C#进行开发、都提供了MVC、Entity Framework、Identity等组件来快速构建应用程序。css
本文将经过迁移一个简单的ASP.NET应用为例,来介绍ASP.NET与ASP.NET Core之间的异同,其主要内容有:
● .Net Core & ASP.NET Core & .Net Standard
● ASP.NET应用迁移分析
● 类库项目迁移
○ 经过建立新项目完成类库迁移
○ 迁移EntityFramework
● 迁移ASP.NET MVC
○ 建立一个新的ASP.NET Core MVC项目
○ 路由迁移
○ 过滤器迁移
○ 依赖注入迁移
○ Web静态资源及View迁移
● 小结html
注:本文使用的VS2017为15.6.4版本,.Net Core SDK版本为2.1.103。前端
在介绍如何迁移ASP.NET应用以前,先了解一下新框架.Net Core和ASP.NET Core,.Net Core是一个全新开发平台,新的运行时、SDK、类库、工具(编译工具、项目模板生成工具等等),而ASP.NET Core则是基于.Net Core的一个Web应用开发框架,它们的关系实际上与.Net Framework和ASP.NET是同样的。
可是在使用.Net开发的时候出现了一个新的名词.Net Standard,.Net Standard是一个可用于全部.Net程序的API标准,换句话说就是若是使用.Net开发的API(类库)符合.Net Standard,那么该类库将能够用于全部的.Net应用。以下表所示,若是开发的类库是以.Net Standard2.0标准开发的,那么该类库将可应用到.Net Core2.0、.Net Framework4.6.1(须要.NET Core2.0的SDK支持)、Mono5.四、Xamarin、UWP等平台的应用上。数据库
更多关于.Net Standard的内容可参考文档:https://docs.microsoft.com/en-us/dotnet/standard/net-standardnpm
.Net Core虽然是一个全新的开发平台(新运行时、新SDK、新类库、新工具),可是它毕竟是以.Net Framework为基础,因此对于部分API来讲它仍然是参照且兼容.Net Framework的,因此在迁移.Net Core应用时能够先对代码进行分析。
一、使用工具分析代码:
有一个名为.Net Portability Analyzer的工具专门用于分析代码和引用程序集在.Net不一样平台上的支持状况,该工具能够在VS的拓展管理中搜索并安装,或者到页面上下载VS插件双击安装(https://marketplace.visualstudio.com/items?itemName=ConnieYau.NETPortabilityAnalyzer):json
安装完成后在VS的解决方案窗口中右键解决方案或者项目就能够看到下图两个菜单项,分别用于分析程序集的可移植性和对移植分析器的配置:gulp
移植分析器的配置主要是对目标平台和报表输出类型进行配置:服务器
下图是对My Blog应用进行可移植性分析的Excel报表(部分):
可移植性总结:mvc
问题细节:框架
缺失的程序集:
注:没找到更多关于缺乏程序集的解释,不肯定是没法解析仍是无兼容性,本文暂时将这些程序集理解为仅支持.Net Framework平台。
从分析报告中能够看出,除了MVC项目,其它类库项目与.Net Core或者.Net standard标准的兼容程度均为100%。
二、根据实际状况对项目引用进行分析:
工具对代码的分析仅可参考,毕竟使用.Net Framework开发的应用可能引用了不少第三方类库,这些类库可能不支持其它平台,有些类库可能支持,可是对于原有版本有了不少Break Changes,使用方法与原先不一致了,因此在进行代码迁移以前对项目引用进行分析,从技术上分析代码迁移是否可行。
本例中仓储的实现依赖了Entity Framework、EF MySQL、Autofac、Identity等组件,这些组件在.Net Core下也是有相应实现,虽然API会有改动,但技术上是没有问题的能够迁移。接下来就开始介绍如何完成迁移。
如今.Net Core项目与.Net Framework项目同样都是使用MSBuild格式的csproj文件来管理项目的相关属性,如名称、版本号、包依赖、项目依赖等等,因此实际上项目的迁移最大的改动就是将csproj的内容改成.Net Core的便可(.Net Core的csproj文件详情参考文档:https://docs.microsoft.com/en-us/dotnet/core/tools/csproj),改动csproj文件有两种方法,若是熟悉文件格式,那么直接改动原有文件便可,若是不熟悉那么能够经过从新建立项目的方式,让VS来完成建立/修改工做。
本文将经过从新建立项目的方式来完成项目迁移,以保证csproj配置文件的正确性。
首先经过VS建立一个.Net Standard的类库项目:
而后把相应的代码复制到新建项目的目录下,删除不存在的命名空间便可。
注:.Net Core会自动识别项目目录下的代码文件,而原来的.Net Fx项目须要在csporj文件中引入,因此这里直接复制代码文件便可识别到项目中。
本例程序中用于实现仓储的类库依赖了EF,而实现MySQL EF的类库还依赖了My SQL的EF相关组件。
另外随着.Net Core的推出,EF也推出了EFCore,另外新版本的.Net大量引入了Options模式来对程序进行配置,关于Options模式可参考文档:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-2.1
中文文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?tabs=basicconfiguration
因此在迁移EF的时候,除了建立新的项目,还须要安装新的Nuget包而且修改相应的配置代码:
1. 安装EFCore组件:
安装Microsoft.EntityFrameworkCore:
2.处理EFCore的配置:
EFCore配置文档:https://docs.microsoft.com/zh-cn/ef/core/miscellaneous/configuring-dbcontext
注:EFCore针对不一样数据库的配置信息经过DbContextOptions对象完成,因此构造方法再也不是一个简单的链接字符串,另外EFCore提供了针对ASP.NET Core容器的依赖注入方法,为了利用依赖注入能够把DbContext配置交由ASP.NET Core项目完成,包括对不一样数据源的支持。
经过上面的方法便可把例子中的类库项目完成迁移,接下来进行MVC项目的迁移工做。
ASP.NET Core是一项变革,除了跨平台以外,它还改变了原先ASP.NET的思想和开发方式,如MVC及API的Controller合二为1、拥抱现代前端开发方式方法、Dorcker支持等,接下来将经过介绍其迁移过程来了解ASP.NET与ASP.NET Core的异同。
相对与类库来讲MVC项目的迁移要复杂的多,由于新的ASP.NET在项目文件结构、程序启动、开发方式等方面都有了区别,这里仍然使用建立新项目的方式完成ASP.NET MVC应用的迁移:
建立一个ASP.NET Core MVC应用:
下面是新项目的目录结构:
ASP.NET Core MVC与原先ASP.NET MVC相似核心仍然是Controllers、Models、Views三个目录,另外经过wwwroot目录对HTML资源进行了整合、配置文件变动为Json格式、删除了Global.asax取而代之的是Program.cs和Startup.cs文件。
ASP.NET开发的Web应用程序须要IIS做为宿主才能够运行,而ASP.NET Core做为一种可跨平台的Web应用开发框架其应用一定是与IIS彻底解耦的,因此它的启动方式也彻底不同。
ASP.NET Core中引入了Program类型,如Console应用同样经过Main方法来运行程序,而ASP.NET Core的Main方法主要内容是指明一个Startup类型完成Web服务器的建立。而Startup类型则负责了整个应用的配置和HTTP请求管道搭建的任务,因此首先要完成的工做就是将原先Global及Owin Startup文件中的内容移植到Startup文件中,下面就开始详细介绍ASP.NET Core MVC的变化及迁移方法。
MVC除了包含Controller、Model、View等文件外,还须要进行路由、过滤器等功能配置,因此首先须要将原项目的相关文件(controller、model、view等注:由于原项目和ASP.NET Core的MVC都依赖Identity实现用户管理功能,因此涉及到用户管理的部分不须要复制)复制到新项目中,修改命名空间引用如:System.Web.Mvc->Microsoft.AspNetCore.Mvc并修复其它命名空间引用错误。
接下来完成其它几个重要方面的迁移。
将原有的路由配置包含Area的路由配置转移至Startup类型的Configure方法中:
注:本例存在Controller名称重名状况,但ASP.NET Core MVC没有提供如ASP.NET中经过命名空间区别的方式区别Controller重名,本例经过修更名称解决问题,如需命名空间区分Controller可参考:https://stackoverflow.com/questions/34306891/restrict-route-to-controller-namespace-in-asp-net-core
全局过滤器的配置则是由原来的经过FilterConfig对象注册改成Startup的ConfigureServices方法中对MVC进行配置:
ASP.NET Core内置了依赖注入功能,甚至一些组件都提供了专门的拓展方法将其服务添加到容器中,如EFCore、Identity、MVC。
上图为ASP.NET Core默认的为将DbContext、Identity以及MVC相关服务添加到容器的代码,除此以外为了顺应依赖注入思想,这里将原有代码的仓储和服务类型均注册到容器中,其依赖经过构造方法进行注入。
仓储代码:
业务代码:
控制器代码:
服务注册代码:
注:本例中实现依赖的是实现而非抽象,这不符合依赖倒置原则,因此此处仅做为ASP.NET Core依赖注入使用示例。另外为了让EFCore支持MySQL,因此须要在项目中添加Pomelo.EntityFrameworkCore.MySql组件:
ASP.NET的页面是基于HTML实现的,一个ASP.NET的页面除了HTML代码外还会引用一些外部静态资源,如css、js、image、font等内容,而ASP.NET中专门提供了Bundle技术来管理这些资源(可参考:《ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理》),那么ASP.NET Core是如何管理这些资源的呢?
首先要处理ASP.NET Core中静态文件的访问问题,在ASP.NET中因为它依赖IIS,而静态文件访问已经被IIS处理了,因此程序中无需关心,但ASP.NET Core不同,须要在其请求管道中添加相应的处理中间件:
注:ASP.NET Core项目模板默认添加该中间件。
对于静态资源的管理ASP.NET Core经过bundleconfig.json配置文件进行配置取代了原先的BundleConfig类型。把原先的资源文件复制到ASP.NET Core的wwwroot目录下,而后在bundleconfig.json文件下进行配置,以下图(部分):
完成配置后还须要在项目中添加一个BuildBundlerMinifier的组件:
引入BuildBundlerMinifier后编译项目就会触发资源绑定和最小化操做:
注:和ASP.NET不一样,Core里面的静态资源管理是在编译过程当中处理的,而且经过一个json配置文件完成处理定义,除了BuildBundlerMinifier外还可使用Gulp等工具完成资源的优化,关于Gulp的使用可参考:https://docs.microsoft.com/en-us/aspnet/core/client-side/bundling-and-minification?view=aspnetcore-2.0&tabs=visual-studio%2Caspnetcore2x#consume-bundleconfigjson-from-gulp
完成静态资源迁移后由于Bundle机制的改变还须要对View中资源引用进行修改(ASP.NET Core中再也不提供@Scripts和@Styles类型来渲染样式和脚本引用):
运行结果:
.Net Core是一个新的开发框架,2.0版本的.Net Core已经相对完善,本文介绍了一个简单的ASP.NET MVC迁移至.Net Core的例子,从例子中能够看出新的开发平台已经实现了原有的全部功能和解决方案,甚至在原有基础上进行了改进。另外.Net Core做为新框架它是开源的而且相对于.Net Framework来讲它的文档更全面(中文文档相对落后),因此.Net Core更容易学习和使用。
对于迁移来讲,首先仍是看需求和目的,为何要进行迁移?为了容器化?跨平台部署?在真实项目中迁移一个项目是很是复杂且具备风险的,因此若是要进行迁移须要慎重考虑,考虑迁移是不是最好的解决方案。
参考:
http://crbtech.in/Dot-Net-Training/9-things-know-converting-asp-dot-net-to-dot-net-core/
https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-2.1
https://docs.microsoft.com/en-us/aspnet/core/client-side/bundling-and-minification?view=aspnetcore-2.1&tabs=visual-studio%2Caspnetcore2x
https://stackoverflow.com/questions/34306891/restrict-route-to-controller-namespace-in-asp-net-core
https://docs.microsoft.com/en-us/aspnet/core/migration/proper-to-2x/?view=aspnetcore-2.1