從ASP.NET 升級到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. 上路吧。html

The Random Acts of Kindness home page.
The Random Acts of Kindness home page.前端

版權說明

http://www.codesnippet.info/ 手工翻譯了本文,擁有完整的版權。請勿進行未受權的轉載。
更好的閱讀體驗:從ASP.NET 升級到ASP.NET5(RC1)jquery

本網站受權轉載git

博客園 www.cnblogs.com
簡書 www.jianshu.comgithub

譯者注:當前時間點,MVC6 RC2已經Release了。web

The Random Acts 網站

我原創了RandomActs這樣的一個網站,本來是爲了我在2013年和2014年關於單元測試的一些演講(talk)。RandomActs是一個架空的用來跟蹤別人的善舉的網站。這是一種相似於作善事(「do good」譯者注:呵呵。。。)的在線社交活動的項目。你使用它來建立Acts (事件), Actors (志願者), 而後將 actors 和 acts進行配對.全部的數據被保存在一個SQL Server數據庫中,一共有3張表格RandomActs, RandomActors, and RandomActActors。shell

RandomActs 作得比通常的僅僅使用框架的Demo要好。 它使用了repository 類(譯者注:貌似沒有好的中文對應,EF術語) 它的 controllers也涉及到了使用依賴注入(dependency injection )的 repository 類 . 他還使用了 Entity Framework 的延遲加載特性(Lazy Load) 來計算Acts和Actors的數量. 同時他還內置了一個「等待隊列」,若是志願者的數量超過了須要作的善舉的數量(譯者注:活來不及幹,就排隊唄)。數據庫

儘管下文所要描述的步驟是爲了個人程序定製的,可是我相信,這也會和你的程序類似,因此你最好可以按照步驟來升級。顯而易見,若是您的項目很複雜,尤爲你的解決方案包含了多個項目(Project),使用了不少第三方庫(譯者注:若是你的第三方庫不支持NET Core,好比使用了不少繪圖的庫,只能呵呵了),你可能須要作更多的工做。不管如何,但願本文至少可以給你指出一條明道在升級這條都是坑的路上。express

版本和代碼庫

本文使用的是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)json

遷移步驟

事前準備

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.cs

app.UseMvc(routes =>
{
   routes.MapRoute(
      name: "default",
      template: "{controller=Act}/{action=Index}/{id?}");
}

第十二步: 修復路由 設定Repository類的依賴注入( Dependency Injection )

startup.cs. 添加這些 ConfigureServices 方法去實現依賴注入吧。

services.AddScoped<IRandomActRepository, RandomActRepository>();
services.AddScoped<IRandomActorRepository, RandomActorRepository>();
services.AddScoped<IRandomActActorRepository, RandomActActorRepository>();

每個控制器有兩個構造器,第一個如今不須要了,應爲上面的依賴注入已經代勞了。那就幹掉第一個構造器吧,就是帶有this的擴展方法的構造器。

public ActController() : this(new RandomActRepository())
{
}

第十三步:修改Repository 類中對於 DbContext 的引用,來支持Dependency Injection

  1. 將這些在RAOKContext 類中的構造器幹掉,在 RAOKContext.cs (你也能夠幹掉整個構造器)
: base("RandomActsDB")
  1. 這樣整個工程如今就不會報錯了,世界就清淨了。若是還有錯誤,好好的看一下還有什麼漏網之魚。若是你如今就急不可耐想要運行工程,呵呵,一個運行時所與正在路上。你還木有一個數據庫鏈接呢。這個錯誤有時候會讓你抓狂( head scratching ),直到你靈光乍現( "ah ha" moment)意識到你的repository類須要修改用來支持injected DbContex的接受者。(modified to receive the injected DbContext.)

  2. 繼續修改吧,每個Repository類,去掉這行代碼
RAOKContext context = new RAOKContext();
  1. 將上面的代碼改爲這個樣子
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)

ASP.NET從MVC5升級到MVC6 總目錄

相關文章
相關標籤/搜索