NET5
ASP.NET5(RC1) - 翻译
前言
ASP.NET 5 是一次令人惊叹的对于ASP.NET的创新革命. 他将构建目标瞄准了 .NET Core CLR, 同时ASP.NET又是对于云服务进行优化,并且是跨平台的框架.很多文章已经称赞过了新的平台的优点. 但是在这篇文章中,我将展示给大家一个用VisualStudio2013,ASP.NET 4.5,MVC5,Entity Frameworkd 7编写的小型的Demo,然后将其升级到VisualStudio2015,ASP.NET 4.5,MVC5,Entity Frameworkd 7。这个新的网站将能同时运行在.NET 4.6 CLR 和 .NET Core CLR. 上路吧。
The Random Acts of Kindness home page.
版权说明
http://www.codesnippet.info/ 手工翻译了本文,拥有完整的版权。请勿进行未授权的转载。
更好的阅读体验:从ASP.NET 升级到ASP.NET5(RC1)
本网站授权转载
博客园 www.cnblogs.com
简书 www.jianshu.com
译者注:当前时间点,MVC6 RC2已经Release了。
The Random Acts 网站
我原创了RandomActs这样的一个网站,原本是为了我在2013年和2014年关于单元测试的一些演讲(talk)。RandomActs是一个架空的用来跟踪别人的善举的网站。这是一种类似于做善事(“do good”译者注:呵呵。。。)的在线社交活动的项目。你使用它来创建Acts (事件), Actors (志愿者), 然后将 actors 和 acts进行配对.所有的数据被保存在一个SQL Server数据库中,一共有3张表格RandomActs, RandomActors, and RandomActActors。
RandomActs 做得比一般的仅仅使用框架的Demo要好。 它使用了repository 类(译者注:貌似没有好的中文对应,EF术语) 它的 controllers也涉及到了使用依赖注入(dependency injection )的 repository 类 . 他还使用了 Entity Framework 的延迟加载特性(Lazy Load) 来计算Acts和Actors的数量. 同时他还内置了一个“等待队列”,如果志愿者的数量超过了需要做的善举的数量(译者注:活来不及干,就排队呗)。
尽管下文所要描述的步骤是为了我的程序定制的,但是我相信,这也会和你的程序相似,所以你最好能够按照步骤来升级。显而易见,如果您的项目很复杂,尤其你的解决方案包含了多个项目(Project),使用了很多第三方库(译者注:如果你的第三方库不支持NET Core,比如使用了很多绘图的库,只能呵呵了),你可能需要做更多的工作。无论如何,希望本文至少能够给你指出一条明道在升级这条都是坑的路上。
版本和代码库
本文使用的是Beta 8 updated for RC1 ,源代码如下:
The ASP.NET 4.x version of the project can be cloned here: https://github.com/plitwin/RandomActs.git
The ASP.NET 5 (RC1) version can be cloned here: https://github.com/plitwin/RandomActs5.git
大伙看清楚啊,是Beta8!!!
大伙看清楚啊,是Beta8!!!
大伙看清楚啊,是Beta8!!!
(Important Thing Repeat Three Times)
迁移步骤
事前准备
ASP.NET5的项目结构和之前的ASP.NET项目结构可谓了天壤之别啊。
- 所有的代码都在src目录底下了。(以前是在Project下面的)
- 所有的静态文件都放到了wwwroot子文件夹下面去了。
- web.config 木有了。。取而代之的是一系列的JSON文件,最重要的是 project.json.
- Global.asax 也木有了。。路由设定( Routing)放在一个新的文件了 startup.cs.
- startup.cs 也可以依赖注入的(dependency injection ),只是默认不启用罢了。
这就意味着,你不能舒舒服服的用VS2015打开MVC6工程,然后按下一个诸如叫做“升级”的按钮,泡一杯咖啡和前台小姑娘聊聊天,接受一个天猫快递,打一盘LOL,然后就大功告成了。别做梦了,至少现在还没有这个一个按钮,也不知道以后会不会有。(It doesn't exist. Not at this point,not sure if it ever will.)。你也别指望能够新建一个空的ASP.NET5的工程,然后将你现在的代码拖曳进来,然后就完事了。由于一些根本性的变更,一些必要的升级手段是必须的。
盗图:来自于 Visual Studio 2015 开发 ASP.NET 5 有何变化?
第一步,新建一个工程
新建一个工程,输入解决方案名称,以下省略500字。注意,选择 ”No authentication “,当然如果你愿意,也可以保留标准配置。
这个时候,你最好试试看,能不能编译成功,是不是会有诡异的错误,有没有出来欢迎页面。
(译者注:可能Package展开错误,或者其他错误,按照惯例,重新启动VS,13.8384%的概率可以修复这个问题。修不好就上博客园,百度,雅虎,天猫,京东看看,反正也修不好,不如先血拼一下)
第二步: 复制现有的文件
是时候复制文件了(Time to do something). 由于前文所诉,两个版本之间差距蛮大的,所以请按照下面的步骤做。
新建一个Models文件夹,将原工程的Model文件都放在新工程的Models文件夹中。
复制所有的Controller文件到新的文件夹中。
复制所有View到新的View中
Act
ActActor
Actor
别复制其他的View啊。。。
第三步: 复制导航栏
鉴于ASP.NET 5 对 _Layout.chshtml 文件做了重大修改 (客户端如何或许文件), 请将下面的代码段放到你的_Layout.cshtml 。(在哪?Shared views下面)
- 修复标题(title),这样就可以明显标识出这是你的网站。将你原来页脚的代码页放到 footer 标签中吧。(译者注:语义化HTML5)
- 使用新的Tag-Helper系统来新建一个指向Home的链接。(译者注:呵呵,前端工程师看着很开心,和HTML语法好像啊)
<a asp-controller="Home" asp-action="Index" class="navbar-brand">New Project</a>
将 “Home” 改为 “Act”, 将所有 “New Project” 改为 “Random Acts of Kindness”.
接下来修改所有的导航链接吧,当然也是使用高大上的Tag-Helper,最后的完成效果应该如下所示。Great。。
这一步大部分人都可以无障碍理解的吧。。。
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-controller="Act" asp-action="Index">Events</a></li>
<li><a asp-controller="Actor" asp-action="Index">Volunteers</a></li>
<li><a asp-controller="Act" asp-action="About">About</a></li>
<li><a asp-controller="Act" asp-action="Contact">Contact</a></li>
</ul>
</div>
第四步: Entity Framework 7 登场
打开 project.json添加下面一个配置项目 (这样的话Nuget就会开始下载这两个Package了):
"EntityFramework.Commands": "7.0.0-rc1-final",
"EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final"
别忘了再添加这个 project.json:
"ef": "EntityFramework.Commands"
别问我有什么用,我不懂EF
第五步:Connection String
appsettings.json: 看清楚了,不是project.json!!!
"ConnectionStrings": {
"RandomActsDB" : "Server=.;Database=RandomActs5DB;Trusted_Connection=True;MultipleActiveResultSets=True;"
}
这里认为你用的是高大上的MSSQL,其他数据库爱好者(MongoDB是最好的数据库),请酌情修改。
第六步:注册EF的Dependency Injection
又是我不懂的EF。。。。
下面的这些加在 startup.cs:
using Microsoft.Data.Entity;
using RandomActs.Models;
Add the following code to the Configure Services method.
var cnx = Configuration.Get<string>("ConnectionStrings:RandomActsDB");
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<RAOKContext>(options => options.UseSqlServer(cnx));
第七步: 全局检索和替换
开始放大招了,全局替换。。。老外胆够肥啊。。。。
要么我也替换”Replace“ 为 ”替换“ 。。。
Replace "System.Data.Entity" with "Microsoft.Data.Entity"
Replace "System.Web.Mvc" with "Microsoft.AspNet.Mvc"
Replace "using System.Web;" with an empty string (effectively deleting all these using statements)
Replace "HttpStatusCode.BadRequest" with "(int) HttpStatusCode.BadRequest"
第八步:修复 Bind 语法
Bind 特性的语法已经简化了(别简化啊。。。).你可以用新的语法来代替 [Bind(Include="item1, item2, item3")], 现在可以这样用了 [Bind("item1","item2","item3")] . 举个栗子。。。。
变身前
public ActionResult Edit([Bind(Include="RandomActId,Title")] RandomAct randomact)
变身后
public ActionResult Edit([Bind("RandomActId","Title")] RandomAct randomact)
友情提示:
编译一下,看到一大推错误信息,你就知道那些地方需要修改了。(作者原文啊)
第九步: 修复 SelectList
任何使用SelectList 方法的Controller,添加引用
using Microsoft.AspNet.Mvc.Rendering;
继续友情提示,看看令人抓狂的ErrorList吧
第十步:修复 Entity Framework Find 方法
在 repository 类中, 替换所有Entity Framework Find 方法为 SingleOrDefault 方法 包括所有lambda expression限制返回件数的地方
举个栗子:
变身前
context.RandomActors.Find(id);
变身后
context.SingleOrDefault(x => x.RandomActorId == id);
第十一步: 修复路由
startup.cscsharp app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Act}/{action=Index}/{id?}"); }
第十二步: 修复路由 设定Repository类的依赖注入( Dependency Injection )
startup.cs. 添加这些 ConfigureServices 方法去实现依赖注入吧。
csharp services.AddScoped<IRandomActRepository, RandomActRepository>(); services.AddScoped<IRandomActorRepository, RandomActorRepository>(); services.AddScoped<IRandomActActorRepository, RandomActActorRepository>();
每一个控制器有两个构造器,第一个现在不需要了,应为上面的依赖注入已经代劳了。那就干掉第一个构造器吧,就是带有this的扩展方法的构造器。csharp public ActController() : this(new RandomActRepository()) { }
第十三步:修改Repository 类中对于 DbContext 的引用,来支持Dependency Injection
- 将这些在RAOKContext 类中的构造器干掉,在 RAOKContext.cs (你也可以干掉整个构造器)
csharp : base("RandomActsDB")
这样整个工程现在就不会报错了,世界就清净了。如果还有错误,好好的看一下还有什么漏网之鱼。如果你现在就急不可耐想要运行工程,呵呵,一个运行时所与正在路上。你还木有一个数据库连接呢。这个错误有时候会让你抓狂( head scratching ),直到你灵光乍现( "ah ha" moment)意识到你的repository类需要修改用来支持injected DbContex的接受者。(modified to receive the injected DbContext.)
继续修改吧,每一个Repository类,去掉这行代码
RAOKContext context = new RAOKContext();
将上面的代码改成这个样子
public RAOKContext context { get; private set; }
public RandomActActorRepository(RAOKContext raokcontext)
{
context = raokcontext;
}上面的是RandomActActorRepository的示范. 构造器的名字不要搞错啊。
第十四步: 新建数据库
我起初无意将这步也添加进来的,因为我是通过迁移一个现存的数据库来取代新建的。
回头细想,可能你没有一个数据库,所以你可能需要一些新建数据库的命令。
这些可怜的命令你执行一次就可以了。打开VS 命令提示(command prompt ),切换到Project文件夹,轻轻键入下面的命令,然后就可以了。
dnx ef migrations add CreateRandomActsDB
dnx ef database update
这样的话,数据库的基本雏形就完成了,使用EF的迁移工具,提交更改给SQLServer,然后就么有然后了。
友情提示: ef 将需要第五步的Connection String!!如果发生错误,瞅瞅第五步做对了吗,
第十五步 去掉 jqueryval Script References
一些页面使用到了不再需要的script bundle,这样会出现运行时错误,将这些代码从页面的最底下删掉就可了。
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
第十六步:修复Lazy Loading
如果你现在屁颠屁颠的开始运行你的代码,一个”ArgumentNullException: Value cannot be null.“错误将会不期而遇。
为什么呢?EF7 RC1还没有实现 lazy loading!!!!!(我和我的小伙伴都惊呆了)
如果你使用过之前版本的EF,你应该体验过魔术般的LazyLoading(the magic of lazy loading)隐示的(implicitly )按需求加载需要的数据。但是现在这个版本的EF,它隔屁了。(或许现在已经实现了,EF不懂的路过)
解决方式是,显示的(explicitly)在需要数据之前,就加载他们。
(本人不懂EF,下面这段,大伙看着办吧。不误人子弟了)
The solution is to explicitly enable eager loading whenever related entities will be needed for a given entity. The RandomActs app took advantage of lazy loading for the volunteer dropdown in the ActActorContoller class and for the counts that are displayed on the views of the ActController and the ActorController classes.
从ActController的 Index 方法中将延迟加载换成抢先加载:
变身前
return View(actRepository.All);
变身后
return View(actRepository.AllIncluding(x => x.Actors));
ActorController也如法炮制
变身前
return View(actorRepository.All);
变身后
return View(actorRepository.AllIncluding(x => x.Acts));
ActActorController也是如此. 不过考虑到第十步的SingleOrDefault 问题,请这样修改
变身前
return context.RandomActs.SingleOrDefault(x => x.RandomActId == id);
变身后
return this.AllIncluding(x => x.Actors).SingleOrDefault(x => x.RandomActId == id);
RandomActActorRepository也如法炮制
变身前
return context.RandomActActors.Where(x => x.RandomActId == actId);
变身后
return context.RandomActActors.Where(x => x.RandomActId == actId).Include(x => x.Actor).Include(x => x.Act);
最后是 ActActorController
变身前
return context.RandomActActors.SingleOrDefault(x => x.RandomActActorId == id);
变身后
return context.RandomActActors.Include(x => x.Actor).Include(x => x.Act).SingleOrDefault(x => x.RandomActActorId == id);
可选
RandomActs现在可以无障碍运行了,不过,如果你想更加有ASP.NET5的范,你还可以更加优化代码
继续全局检索替换 "ActionResult" 为 "IActionResult".
将Html helper 方法改为Tag Helper ,如果你闲的蛋疼。
变身前
@Html.TextBoxFor(model => model.Title, new { style = "width: 400px" })
变身后
<input asp-for="Title" style="width: 400px" />
变身前
@using (Html.BeginForm())
{
}
变身后
<form asp-controller="Act" asp-action="Edit" method="post">
</form>
感谢网友的指正
引用dudu的文章 http://www.cnblogs.com/dudu/p/dotnet-core-framework-mono.html
在.NET Core推出之前,.NET Core是参考.NET Framework重新开发的.NET实现,Mono是.NET Framework的一个开源的、跨平台的实现。
如果拿操作系统打个比方,这时,.NET Framework是Unix,.NET Core是Linux,Mono是Mac OS X。
在.NET Core推出之后,.NET Framework与Mono将基于.NET Core重新构建。.NET Framework将成为.NET Core在Windows上的一个发行版,Mono将成为.NET Core的一个跨平台发行版。
再拿操作系统打个比较,那时,.NET Core是Linux,.NET Framework是Ubuntu,Mono是Red Hat。
原文来自于 Migrating an ASP.NET MVC 5 App to ASP.NET 5 (RC1)
NET5的更多相关文章
- 让ASP.NET5在Jexus上飞呀飞
就在最近一段时间,“Visual Studio 2015 CTP 5”(以下简称CTP5)发布了,CTP5的发布不仅标志着新一代的VisualStudio正式发布又向前迈出了一步,还标志着距离ASP. ...
- 为支持ASP.NET5跨平台,Jexus再添新举措
Jexus作为一款运行于Linux/FreeBSD平台上,以支持ASP.NET著称的高性能HTTP服务器和反向代理服务器,继5.6版完成对OWIN标准应用的支持后,就把着力点放到了对ASP.NET5的 ...
- 从ASP.NET 升级到ASP.NET5(RC1) - 翻译
前言 ASP.NET 5 是一次令人惊叹的对于ASP.NET的创新革命. 他将构建目标瞄准了 .NET Core CLR, 同时ASP.NET又是对于云服务进行优化,并且是跨平台的框架.很多文章已经称 ...
- ASP.NET5,MVC 6,Beta 7与VS 2015 RTM的兼容问题
温馨提示:本文杂而乱,最终不知所云. Visual Studio 2015 RTM已经于2015年7月20号正式发布,我也在第一时间下载安装了起来. 虽然在5月份就开始使用RC版本,但是还是很期待正式 ...
- ASP.NET5 Beta8可用性
ASP.NET5 beta8现已上都的NuGet作为一个工具升级到Visual Studio2015!此版本极大地扩展.NET核心对OS X和Linux所支持的范围.您现在可以使用网络,加密和全球化特 ...
- ASP.NET5 MVC6入门教学之一(自己动手)
等待微软开源大动作已经好几年了,终于ASP.NET 5发布了.今天给新手们写一个简单地教程,教你认识一下ASP.NET5 MVC6 1.安装kvm 首先,你需要以管理员权限打开cmd,执行如下的脚本: ...
- ASP.NET5 中静态文件的各种使用方式
所谓静态文件,包含HTML文件,css文件.图片文件和js文件等,他们是服务器直接读取到客户端的一些资源,在这篇文章中,我们将解释关于ASP.NET5和静态文件的一些内容. 服务端的静态文件 默认情况 ...
- IIS 上发布ASP.NET5
原文 http://docs.asp.net/en/latest/publishing/iis.html 1.安装HTTP Platform Handler ,这个是必需的,不然无法通过IIS访问AS ...
- ASP.NET5配置
ASP.NET5支持各种各样的配置,应用程序配置数据可以来自JSON, XML或者INI格式的文件,也能来自环境变量,你也可以自定义你自己的Configuration Provider. 1. 获取和 ...
- ASP.NET5中间件
小的应用组件可以包含到Http请求管道当中,ASP.NET5 集成了中间件,被包在了应用程序的Configure方法当中. 1. 什么是中间件 中间件是一组被装到应用程序管道的请求和响应中的组件.每一 ...
随机推荐
- Arduino 入门程序示例之一片 LED(2015-06-11)
概述 从点到线,从线到面.现在开始要来一片的 LED 了,一大波的 LED 正在到来! 示例程序 因为手头没有现成的模块,手头只有 595,所以这里每一个示例程序都是使用 74HC595 扩展 IO ...
- 四、Nginx负载均衡upstream
user www; worker_processes ; error_log /usr/local/nginx/logs/error.log crit; pid /usr/local/nginx/lo ...
- WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇]
原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇] 在<上篇>中,我通过使用Delegate的方式解决了服务调用过程中的异常处理以及对服务代理的关闭.对于<WCF技术 ...
- Step by step guide to set up master and slave machines(转)
Note: There is no need to install Jenkins on the slave machine. On your master machine go to Manage ...
- xend调用xenstore的出错揭秘
近期发现几例问题,均是xend里面报了同一个错误 File "/usr/lib64/python2.4/site-packages/xen/xend/xenstore/xstransact. ...
- 关于js基础easy忘记的那些事儿
1.Number() 通过这个函数转化后的值仅仅有两个:数值和NaN,通过parseInt也能转化为数值.可是像"134df"转化后的值为134,而Number("134 ...
- 【AC大牛陈鸿的ACM总结贴】【ID AekdyCoin】人家当初也一样是菜鸟
acm总结帖_By AekdyCoin 各路大牛都在中国大陆的5个赛区结束以后纷纷发出了退役帖,总结帖,或功德圆满,或死不瞑目,而这也许又会造就明年的各种"炸尸"风波.为了考虑在发 ...
- hdu 1075 What Are You Talking About(字典树)
刚学的字典树,代码写得很不熟练.写法上也没有什么特别的优化,就是以1A为第一目标! 可惜还是失败了. 少考虑了一种情况,就是一个单词是另一个单词前缀的问题,写了好久,还是没有1A.不过感觉对字典树有了 ...
- Java读写Word文件常用技术
Java操作操作Word文件,最近花了几天时间解决使用Word模板导出数据的问题,收集到一些资料分享下. 常见的技术如下: 1.POI(兼容doc.docx文件) 官方网站:http://poi. ...
- fzu 1913 Easy Comparison(字符串)
题目链接:fzu 1913 Easy Comparison 题目大意:给出一个字符串,计算与它按照字典序排序排列后的字符串有多少个位置不同. 解题思路:水体,sort一下,然后遍历一遍就好. #inc ...