ASP.NET MVC应用迁移到ASP.NET Core及其异同简介-程序员宅基地

ASP.NET Core是微软新推出支持跨平台、高性能、开源的开发框架,相比起原有的ASP.NET来说,ASP.NET Core更适合开发现代应用程序,如跨平台、Dorker的支持、集成现代前端开发框架(如npm、bower、gulp等等)。另外相比ASP.NET它的性能更好,还内置了依赖注入等功能对开发方式进行了优化。但它们之间也有很多相同或相似的地方,如都使用C#进行开发、都提供了MVC、Entity Framework、Identity等组件来快速构建应用程序。

  本文将通过迁移一个简单的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迁移
  ● 小结

  注:本文使用的VS2017为15.6.4版本,.Net Core SDK版本为2.1.103。

.Net Core & ASP.NET Core & .Net Standard

  在介绍如何迁移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.4、Xamarin、UWP等平台的应用上。

  640?wx_fmt=png

  更多关于.Net Standard的内容可参考文档:https://docs.microsoft.com/en-us/dotnet/standard/net-standard

ASP.NET应用迁移分析

  .Net Core虽然是一个全新的开发平台(新运行时、新SDK、新类库、新工具),但是它毕竟是以.Net Framework为基础,所以对于部分API来说它仍然是参照且兼容.Net Framework的,所以在迁移.Net Core应用时可以先对代码进行分析。
  1、使用工具分析代码:
  有一个名为.Net Portability Analyzer的工具专门用于分析代码和引用程序集在.Net不同平台上的支持情况,该工具可以在VS的拓展管理中搜索并安装,或者到页面上下载VS插件双击安装(https://marketplace.visualstudio.com/items?itemName=ConnieYau.NETPortabilityAnalyzer):

  640?wx_fmt=png

  安装完成后在VS的解决方案窗口中右键解决方案或者项目就可以看到下图两个菜单项,分别用于分析程序集的可移植性和对移植分析器的配置:

  640?wx_fmt=png

  移植分析器的配置主要是对目标平台和报表输出类型进行配置:

  640?wx_fmt=png

  下图是对My Blog应用进行可移植性分析的Excel报表(部分):
  可移植性总结:

  640?wx_fmt=png

  问题细节:

  640?wx_fmt=png

  缺失的程序集:

  640?wx_fmt=png

  注:没找到更多关于缺少程序集的解释,不确定是无法解析还是无兼容性,本文暂时将这些程序集理解为仅支持.Net Framework平台。
  从分析报告中可以看出,除了MVC项目,其它类库项目与.Net Core或者.Net standard标准的兼容程度均为100%。
  2、根据实际情况对项目引用进行分析:
  工具对代码的分析仅可参考,毕竟使用.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的类库项目:

  640?wx_fmt=png

  然后把相应的代码复制到新建项目的目录下,删除不存在的命名空间即可。
  注:.Net Core会自动识别项目目录下的代码文件,而原来的.Net Fx项目需要在csporj文件中引入,所以这里直接复制代码文件即可识别到项目中。

迁移EntityFramework

  本例程序中用于实现仓储的类库依赖了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:

  640?wx_fmt=png

  2.处理EFCore的配置:
  EFCore配置文档:https://docs.microsoft.com/zh-cn/ef/core/miscellaneous/configuring-dbcontext

  640?wx_fmt=png

  注:EFCore针对不同数据库的配置信息通过DbContextOptions对象完成,所以构造方法不再是一个简单的连接字符串,另外EFCore提供了针对ASP.NET Core容器的依赖注入方法,为了利用依赖注入可以把DbContext配置交由ASP.NET Core项目完成,包括对不同数据源的支持。

  通过上面的方法即可把例子中的类库项目完成迁移,接下来进行MVC项目的迁移工作。

迁移ASP.NET MVC

  ASP.NET Core是一项变革,除了跨平台之外,它还改变了原先ASP.NET的思想和开发方式,如MVC及API的Controller合二为一、拥抱现代前端开发方式方法、Dorcker支持等,接下来将通过介绍其迁移过程来了解ASP.NET与ASP.NET Core的异同。

创建一个新的ASP.NET Core MVC项目

  相对与类库来说MVC项目的迁移要复杂的多,因为新的ASP.NET在项目文件结构、程序启动、开发方式等方面都有了区别,这里仍然使用创建新项目的方式完成ASP.NET MVC应用的迁移:
  创建一个ASP.NET Core MVC应用:

  640?wx_fmt=png

  下面是新项目的目录结构:

  640?wx_fmt=png

  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方法中:

  640?wx_fmt=png

  注:本例存在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进行配置:

  640?wx_fmt=png

  640?wx_fmt=png

依赖注入迁移

  ASP.NET Core内置了依赖注入功能,甚至一些组件都提供了专门的拓展方法将其服务添加到容器中,如EFCore、Identity、MVC。

  640?wx_fmt=png

  上图为ASP.NET Core默认的为将DbContext、Identity以及MVC相关服务添加到容器的代码,除此之外为了顺应依赖注入思想,这里将原有代码的仓储和服务类型均注册到容器中,其依赖通过构造方法进行注入。

  仓储代码:

  640?wx_fmt=png

  业务代码:

  640?wx_fmt=png

  控制器代码:

  640?wx_fmt=png

  服务注册代码:

  640?wx_fmt=png

  注:本例中实现依赖的是实现而非抽象,这不符合依赖倒置原则,所以此处仅作为ASP.NET Core依赖注入使用示例。另外为了让EFCore支持MySQL,所以需要在项目中添加Pomelo.EntityFrameworkCore.MySql组件:

  640?wx_fmt=png

Web静态资源及View迁移

  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不一样,需要在其请求管道中添加相应的处理中间件:

  640?wx_fmt=png

  注:ASP.NET Core项目模板默认添加该中间件。
  对于静态资源的管理ASP.NET Core通过bundleconfig.json配置文件进行配置取代了原先的BundleConfig类型。把原先的资源文件复制到ASP.NET Core的wwwroot目录下,然后在bundleconfig.json文件下进行配置,如下图(部分):

   640?wx_fmt=png

  完成配置后还需要在项目中添加一个BuildBundlerMinifier的组件:

  640?wx_fmt=png

  引入BuildBundlerMinifier后编译项目就会触发资源绑定和最小化操作:

  640?wx_fmt=png

  注:和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类型来渲染样式和脚本引用):

  640?wx_fmt=png

  640?wx_fmt=png

  运行结果:

  640?wx_fmt=png

小结

  .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

原文地址 :http://www.cnblogs.com/selimsong/p/8870286.html 


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sD7O95O/article/details/80002028

智能推荐

大学生bootstrap框架网页作业成品 bootstrap响应式网页制作模板 学生家乡网页bootstrap框架网站作品 html静态网页设计制作 dw静态网页成品模板素材网页-程序员宅基地

文章浏览阅读754次,点赞25次,收藏17次。网页作品编辑作品下载后可使用任意HTML编辑软件(如:`DW、HBuilder、NotePAD 、Vscode 、Sublime 、Webstorm、 Notepad++ 等任意HTML软件编辑修改网页)网页作品技术:Div+CSS、鼠标滑过特效、Table、导航栏效果、banner、表单、二级三级页面等,视频、 音频元素 、Flash,同时设计了logo(源文件),基本期末作业所需的知识点全覆盖。

2017年度十大新兴技术,多久才能实现?-程序员宅基地

文章浏览阅读121次。世界经济论坛每年评选年度十大新兴技术。在此前五年的榜单中,3D打印、CRISPR-Cas9、光遗传等技术已经成为我们生活、研究中的重要元素。而在今年的榜单中,又有哪些将改变人类的未来?今年报告中的新兴技术包括将二氧化碳变成燃料的“人造叶子”,以及从空气中获取水的技术,可能很快将在解决全球上最迫切的挑战中发挥作用。这些技术由世界经济论坛的专家和全球未来...

Hive/HiveSQL常用优化方法全面总结_hive/hiveql常用优化方法全面总结-程序员宅基地

文章浏览阅读8k次,点赞17次,收藏167次。Hive作为大数据领域常用的数据仓库组件,在平时设计和查询时要特别注意效率。影响Hive效率的几乎从不是数据量过大,而是数据倾斜、数据冗余、job或I/O过多、MapRe..._hive/hiveql常用优化方法全面总结

电磁工程计算机辅助设计,《ANSYS工程应用教程-热与电磁学篇》-程序员宅基地

文章浏览阅读307次。ANSYS工程应用教程-热与电磁学篇所属分类: 计算机辅助设计与工程计算出版社: 中国铁道出版社作者: 唐兴伦出版时间: 2003/1ISBN书号: 9787113050146本书重点讲述了如何利用ANSYS有限元软件求解目前工程中普遍存在的各种热与电磁学分析问题。本书通过丰富的实例进行讲解,尤其适合刚刚接触ANSYS并渴望快速入门的工程技术人员。全书本着深入浅出的原则,按图形用户界面和命令流两种..._电磁辅助工程

spring boot 自学笔记(三) Redis集成—RedisTemplate_stringredistemplate.execute方法的返回值为long类型时执行的是什么操作-程序员宅基地

文章浏览阅读5.4w次,点赞7次,收藏27次。Spring boot 基于Spring, Redis集成与Spring大同小异。文章示例代码均以前篇笔记为基础增加修改,直接上代码:pom.xml Redis相关依赖:<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmln..._stringredistemplate.execute方法的返回值为long类型时执行的是什么操作

c语言static编程举例,C语言编程习惯与编程要点:static与类-程序员宅基地

文章浏览阅读114次。C语言编程习惯与编程要点:static与类① 不和对象直接相关的数据,声明为static想象有一个银行账户的类,每个人都可以开银行账户。存在银行利率这个成员变量,它不应该属于对象,而应该属于银行这个类,由所有的用户来共享。static修饰成员变量时,该成员变量放在程序的全局区中,整个程序运行过程中只有该成员变量的一份副本。而普通的成员变量存在每个对象的内存中,若把银行利率放在每个对象中,是浪费了内..._c语言 单例 static

随便推点

29.FFmpeg+OpenGLES+OpenSLES播放器实现(三.FFmpeg配置和编译脚本)-程序员宅基地

文章浏览阅读245次。项目源码FFmpeg开发文档编译过程中涉及到很多ndk中的so库和头文件以及交叉编译的工具,在命令执行的时候会在ndk相应的目录下去查找,所以我们可以使用export命令事先将这些路径设置到环境变量,使用的时候可以很方便的找到//NDK加入环境变量,以我的ndk存放路径为例export NDK=/root/renzhenming/ffmpeg/an..._openeuler 安装ffmepg

为什么java中值为单向传递,为什么Java只有值传递?-程序员宅基地

文章浏览阅读101次。释放双眼,带上耳机,听听看~!形参和实参形式参数,是在方法定义阶段,是定义某个函数时使用的参数,用于接收实参传入。例f(x,y)中x和y是形参。实际参数,是在方法调用阶段,是主调函数调用有参函数时,实际传递的内容。例f(3,7)中3和7是实参。值传递和引用传递值传递和引用传递不是简单地通过传递内容区分的。如果是值,就是值传递;如果是引用,就是引用传递。这一理解是不正确的。值传递,是指在调用函数时将..._java 实参向形参的数据传递是单向值传递

Linux Ubuntu Datagrip 开启 Mysql 3306端口 远程访问-程序员宅基地

文章浏览阅读401次,点赞3次,收藏10次。简而言之,Datagrip要想远程连接mysql数据库,就是三步:第一:配置防火墙3306端口第二:修改mysql配置文件/etc/mysql/mysql.conf.d/mysqld.cnf,取消只允许本机ip访问第三步:登录数据库,创建允许指定ip访问的数据库用户。

【java】java 中对象属性和数据库中字段名的转换_java 将查询的数据对象属性 name:测试 转成 姓名:测试-程序员宅基地

文章浏览阅读2.9k次。在开发过程中数据中的字段的命名一般是这样的:user_name book_id 等,而对应的java对象中的属性命名是这样的:userName、bookId等,写了个方法使这2种命名互相转换。/** * 对象属性转换为字段 例如:userName to user_name * @param property 字段名 * @return */ public static ..._java 将查询的数据对象属性 name:测试 转成 姓名:测试

xxl-sso源码解读(基于Cookie)-程序员宅基地

文章浏览阅读1.3k次,点赞4次,收藏12次。讲解xxl-sso源码,帮助了解xxl-sso实现原理和对于跨域单点登录的处理方法_xxl-sso

Python3 time模块使用,精确到秒以内的应用示例_python的datetime.now()精确到秒-程序员宅基地

文章浏览阅读1.4k次。import timeimport datetime # 测试用,方便## 模拟程序执行,调用函数这个动作也要消耗时间def run(): 当前时刻 = datetime.datetime.now() print("函数启动时刻", 当前时刻)## 最后的修正,精确到毫秒def WAIT(延时): T = time.time() T_整数部..._python的datetime.now()精确到秒

推荐文章

热门文章

相关标签