本文章是由機器翻譯。

Azure 網站

雲端教學

James分庭

下載代碼示例

這是一個激動人心的時刻,是 Web 開發人員。創建一個專案並將它部署到一個面向公眾的端點的端到端任務真正是一項挑戰,曾是令人望而生畏,甚至可能讓人望而卻步。然而今天站立的計算的一個"解決"的挑戰。

很少的資源,您可以下載一個免費的 IDE 和原始程式碼控制工具。你可以開始一個專案並將其部署到一個豐富的基礎設施,為您維護而無需訪問或硬體的知識。你可以有你無代價要開始主持的專案。

我們要與工作的構造塊是比以往任何時候更全面 — — 是否 PHP、JAVA或 Microsoft.NET 框架。我們現在可以專注于使用者體驗而不是專案管理、 網路、 存儲、 部署程式或可擴充性。

FrontClass,在這篇文章,涵蓋的應用程式是工作的幾十年前就已經幾周,如果不長的東西。已經是很難得到的所有環境中工作。部署會是一場噩夢。而且,最有可能,就不能夠解決可伸縮性在那段時間一直。今天,我可以生成專案和把它部署在幾個小時,作好準備,規模。可下載的解決方案包含完整的工作的原始程式碼你可以部署而不必修改您自己微軟 Azure 的帳戶。

而志願者在當地的初中高中,教學到程式設計 10 至 14 歲的孩子,我開始 FrontClass。我想要與學生的一種方式可以控制比賽節奏,而讓他們返回到前一步驟上需求分享的內容。有的應用程式的説明教師進行一類的三個功能區域:作文課,課堂教學及學生參與。我將會打破上述每個領域,但是,當然,有一些重疊。

專案基礎知識

若要生成應用程式,我將使用Visual Studio2013年更新 2。創建解決方案和ASP.NETMVC 範本時,我還將使用ASP.NETWeb 應用程式。催生了從範本的專案將使用流行引導前端框架的造型和一些 UI 功能。

若要啟用即時功能,我會添加那麼 SignalR 套裝軟體並使用模具現在知名的Visual Studio。我還將在用戶端頁面上使用的必要 jQuery 庫。我將把配置Entity Framework(EF) 預設情況下,在發展中使用 LocalDb­發展的環境,但當我部署到 Azure 的 Web 網站時,我將使用 SQL Azure 資料庫作為資料存儲區。我開始整個專案,然而,在 Azure 入口網站 (portal.azure.com),在那裡我可以配置我的部署目標。

創建 Azure 網站 在左下角的門戶,按一下新和選擇的網站 + SQL 範本,如中所示的 圖 1。Azure 將創建一組連結的資源。選擇一個適當的名稱為此組和應用程式的名稱。我可以選擇創建一個新的資料庫伺服器或選擇一個現有我要為我的網站創建資料庫的帳戶上。它建議在同一區域,減少網路流量時間有資料庫和 Web 網站。


圖 1 創建一個新的 Azure 網站與連結的資料庫

對我而言,我被稱為資源組 ELearning,FrontClass_DB,資料庫和網站 FrontClass。你需要選擇一個唯一的網站名稱。完成設置後,我得到 frontclass.azurewebsites。淨的主機名稱和我的部署目標是準備好要舉辦我的網站。

儘管不可思議的事件的出現,那裡真的不是應該在這裡讓你大吃一驚。我創建一個 DNS 條目,映射主機名稱到 IP 位址,並作出一些配置選項,如預設文件和連接字串。這些是本質上你會在幕後,讓您的網站運行在 IIS 中做的事情。所以,再一次,它不是神奇的但它是相當方便。也有一些基礎設施類型工具像源控制和部署腳本可用來説明您入門。

創建解決方案下一步,我到Visual Studio頭和選擇上述ASP.NETWeb 應用程式作為一個基地為我的解決方案。當我選擇要創建的專案類型 — — 使用ASP.NETMVC 範本 — — 我也得到選項,以在 Azure 上創建的相關的資源。我已經創建的網站和資料庫通過入口網站,所以我清除該核取方塊,並著手創建網站。

撰寫課程模組

由於這個專案的範圍,我能夠維持一個相當簡單的資料模型。我使用 EF6 創建的模型通過代碼第一,為道路消費者的資料移轉下來的修改敞開了大門。最終的結果,所示圖 2,是一套簡單的代表的課程、 模組和步結構類。


圖 2 基本的應用程式資料模型

那裡是儀式的有點來遍歷得到所有接線在哪裡我想要它。即,我想要使用一個單一的資料庫,我想要能夠以控制遷移時的生成和我想要我的應用程式來自動執行任何傑出的遷移在應用程式啟動。

這讓我顯式控制顯示在每個遷移的變化。它還可以讓我的應用程式更新本身無需干預。我還將設置一種手段來預填充該資料庫的管理員角色與教師角色 (第一次和只有行政使用者) 通過對配置類的種子重寫。

指定的連接字串Entity Framework讓我使用相同的資料庫與不同的上下文和一個單一的連接字串內的遷移。通過調用基類建構函式和傳遞在名稱中,框架將會看起來第一次在應用程式或 Web 配置,看看是否按相同的名稱定義的連接字串。如果是這樣,它將使用它來建立連接。

遷移歷史記錄為每個上下文由測該命名空間作為更新過程的一部分進行維護。這將有助於我彼此獨立地執行遷移。進行此設置,我添加一個預設建構函式到我的上下文類,如下所示:

public FrontClassContext()
  : base("DefaultConnection") { }

如果你看看作為坐落在 IdentityModels.cs 檔中的專案範本的一部分創建的上下文,你會看到那裡是目前類似的預設建構函式。 它略有修改,以反映性質的 IdentityDbCoNtext 的基類,但仍然從 Web.Config 檔中使用 DefaultConnection 的連接字串。

啟用遷移我生成的配置類的由從Visual Studio中的封裝管理員主控台執行下面的命令創建的實體:

Enable-Migrations -ContextTypeName FrontClass.DAL.FrontClassContext

這點亮我的課程-遷移­相關實體。 我想要為 ApplicationDbCoNtext,以及做的一樣。 與換出的類名,我可以再次運行這個命令。 然而,當我啟用配置、 遷移和播種在存儲帳戶的上下文中,我不想覆蓋以前搭建的配置類。 相反,我指定遷移、 備用目錄,如下所示,與遷移­目錄參數傳遞到該命令:

 

Enable-Migrations -ContextTypeName FrontClass.Models.ApplicationDbContext -MigrationsDirectory:"Models\AccountMigrations"

第一次遷移中添加的下一步是要簡單地腳手架Entity Framework將執行的類。 我使用了下面的命令兩次,一次為我要為其創建遷移每個 DbCoNtext:

Add-Migration Initial-Model -ConfigurationTypeName FrontClass.Migrations.Configuration
Add-Migration Initial-Model -ConfigurationTypeName FrontClass.Models.AccountMigrations.Configuration

再次,與多個上下文中工作增加複雜一點的因為您必須指定 ConfigurationTypeName 參數。 否則,這是一個簡單的操作。

設置資料庫初始化策略要配置 EF 自動執行我的遷移,需要告訴它之前執行任何資料庫訪問,使用什麼策略。 如果不這樣做,我就會收到異常消息在運行時,以表明我的模型是與資料庫不同步。 每個到我的課的更改會影響我的資料模型,在資料庫中跟蹤的計算雜湊值。

在我 Global.asax 我添加以下兩行代碼就可以使用 MigrateDatabaseToLatestVersion 初始值設定項:

Database.SetInitializer<ApplicationDbContext>(
  new MigrateDatabaseToLatestVersion
    <ApplicationDbContext, 
     FrontClass.Models.AccountMigrations.Configuration>());
Database.SetInitializer<FrontClassContext>(
  new MigrateDatabaseToLatestVersion
    <FrontClassContext, FrontClass.Migrations.Configuration>());

請注意我要求接受我想要配置的上下文的泛型 SetInitializer 方法。 對我而言,我的配置類像-命名所以我已經指定的充分使用命名空間的類名稱。

種子表第一運行,我想要能夠提供一種體驗,可以讓別人"只需登錄",開始使用的應用程式。 我可以創建類似于你會發現在流行的博客應用程式運行一次控制器。 另一個選擇是在我的配置類中使用的種子的方法。 種子方法被通過在適當的上下文,從中我可以操作的表的一個實例。

與ASP.NET2.0 的身份,我也得到了一套豐富的 EF 意識到的類。 這讓我的角色和使用者有條件地注入資料庫中,就像我圖 3

圖 3 播種的第一個角色和管理使用者

if (!context.Roles.Any(r => r.Name == 
  FrontClass.MvcApplication.AdministratorRoleName))
{
  var roleStore = new RoleStore<IdentityRole>(context);
  var roleManager = new RoleManager<IdentityRole>(roleStore);
  var identityRole = new IdentityRole 
    {Name = FrontClass.MvcApplication.AdministratorRoleName};
  roleManager.Create(identityRole);
}
var instructorName = "instructor@contonso.com";
if (!context.Users.Any(u => u.UserName == instructorName))
{
  var userStore = new UserStore<ApplicationUser>(context);
  var userManager = new UserManager<ApplicationUser>(userStore);
  var applicationUser = 
    new ApplicationUser { UserName = instructorName };
  userManager.Create(applicationUser, "init_2014");
  userManager.AddToRole(applicationUser.Id, 
    FrontClass.MvcApplication.AdministratorRoleName);
}

我也被播種的模組相關的表,用一些示例資料,你可以看到在本文附帶的下載。當應用程式啟動時,我可以使用密碼 init_2014 instructor@contonso.com 使用者名登錄。在這一點上,我在的地方有我的資料結構、 應用程式佈建了多個上下文中使用相同的資料庫和我有一個管理使用者 — — 教練帳戶 — — 這可以登錄。

基本的編輯功能允許實際課程組成是提供創建、 所需的最後一片讀取、 更新和刪除 (CRUD) 功能。我創建一個新的區域稱為管理我的專案的根目錄中,使用內置的腳手架工具來構建使用者介面。最後,我創建管理控制器與一個索引操作和一個視圖,提供課程維護、 模組和步驟的連結。

指導課程

作為教師,您可以從同一個管理檢視,然後從中選擇一個模組選擇一門課程。每個步驟都顯示在後續模組頁面上,正如你可以看到在圖 4。您可以向任何一個學生在虛擬課堂上的內容的訪問講師預覽和發送的任何步驟。


圖 4 行為類

學生們可以在一次會議,在課堂上與教員,或傳播到世界各地。一個上下文,您可以使用此應用程式將是一個即時、 線上的虛擬教室,有幾十個甚至幾百個學生。我想要確保不管如何,您可能需要調整應用程式,你不會失去擴展能力。所以我要考慮怎麼教訓有效載荷實際上會給學生。

您可以為純文字或 html 格式,創建一個課程模組中的步驟,每一步可以是任意長度。那麼 SignalR 做很好的處理談判運輸 (與 Websocket,伺服器發送的事件,長輪詢或永遠幀) 的力學,它抽象需要擔心消息序列化。

最終,為了保持可擴展,我需要保持較小的我的郵件。這是設計的為了儘量減少對伺服器資源的需求,降低成本的序列化,讓用戶端的瀏覽器利用部分的基礎設施,如緩存,那麼 SignalR 在中和使用同樣的它:為發信號。

要實現這一目標的最佳方式是簡單地發送消息到用戶端說,"新的內容就在這裡,"而不是發送整個課一步。收到的在這裡的 JSON 中的用戶端,請考慮下列序列化的消息:

{"H":"ModuleStepHub", "M":"updateStep",
  "A":["\n<h1>Welcome to the course!</h1><p>trimmed for brevity...</p>\n"]}

該消息作為參數負載來為用戶端的 updateStep 方法進行 HTML。 那"裁剪為簡潔起見"文本是關注的源。 內容可顯著增加,根據教練如何創建邁出的一步。 現在,這只是文本。 你可以想像的消息的大小將會如何成長如果您試圖發送內容或管道的圖像的頁面。 將序列化為 JSON 和傳遞到每個用戶端使用的信令的管道資源的文本或圖像。 相反,我只是想要發送的信號,特別是瀏覽器應該載入的新內容 ID。 那小得多的消息看起來更像這樣:

{"H":"ModuleStepHub","M":"notifyStepAvailable","A":[7]}

現在,我知道我想用我的消息來完成,我可以在我的應用程式中建立了此功能。

**創建中心:**我將集線器的資料夾添加到我的專案,然後從添加新項對話方塊中添加那麼 SignalR 集線器類 (v2)。 集線器是伺服器端的一段的那麼 SignalR 您創建發佈消息和處理用戶端調用。 Visual Studio去這條路線,拉在我的依賴關係和與抽樣方法在我中心支架一類。 我刪除的抽樣方法,並創建一個新的讓我發送一條消息,用下面的代碼:

public void MakeStepAvailable(int stepId)
{
  Clients.Others.
notifyStepAvailable(stepId);
}

這裡的前提是行動的課程的教師將調用某種向學生髮送一步。 使用其他用戶端上的動態屬性物件,我告訴那麼 SignalR 一步 ID 向發送所有其他連接的用戶端。 那麼 SignalR 提供大量的這種過濾的選項,所以我可以更新特定的使用者、 一組使用者或一些其他片的連接的用戶端。 集線器也讓教官開始一個新的模組。 學生可以得到由講師提供的步驟的清單。

地圖那麼 SignalR 集線器暴露在我的中心中創建的功能,需要捅那麼 SignalR,作為我的應用程式正在啟動。 對 MapSignalR 的調用設置了一個預設終結點,提供了一個 JavaScript 代理。 當包含在用戶端,這將調用伺服器端方法從用戶端,反之亦然。 我的專案的根資料夾包括我打電話要做配置方法中的佈線浩然啟動類。 這是如何,看起來後我的更改:

public void Configuration(IAppBuilder app)
{
  ConfigureAuth(app);
  app.MapSignalR();
}

它是重要的是在這裡第一次調用 ConfigureAuth。浩然管道將推送消息通過中介軟體中介軟體註冊的順序的。在我們的例子中,我們想要的身份驗證和授權在發生之前,調用到達我們的中樞。

啟用共用讓老師分享的內容,添加,另一個控制器名 InstructController 的應用程式。這有只索引操作。我已經裝飾的類具有授權的屬性,因此只有管理員才可以控制教室。索引操作接受模組 ID 作為參數,在我的 App_Startup\RouteConfig.cs 類中配置的路由。方法查找模組從資料庫,並返回該記錄到視圖與查詢中包括的步驟集合。

相應的視圖 (位於 Views\Instruct\Index.cshtml),只是生成了一個分享按鈕的每一步。我使用的資料 id 屬性來存儲步驟的 ID。我包括那麼 SignalR 圖書館和集線器代理暴露在前面的步驟,然後編寫少量的 JavaScript 來啟動代理和處理 click 事件從教練,如中所示圖 5

圖 5 JavaScript 到啟動代理和處理按一下事件

<script src="~/Scripts/jquery.signalR-2.0.3.js"></script>
<script src="~/SignalR/Hubs"></script>
<script>
  $(function() {
    var hub = $.connection.moduleStepHub;
    $.connection.hub.start().done(function() {
      $(".share-step").click(function() {
        var stepId = $(this).attr("data-id");
          hub.server.makeStepAvailable(stepId);
      });
    });
  });
</script>

最後,我修改我的行政索引頁,包括課程和模組,教師可從中選擇的清單。最後一個介面,作為顯示在圖 6,讓教練跳進一個模組的權利,並開始教學。


圖 6 為 FrontClass 的管理介面

使用模組視圖從圖 4,指導員然後可以發送內容到類。

課堂參與

作為一個學生,這個故事是簡單得多。只是顯示 !每個學生將需要註冊以訪問該網站,並接收活動課程模組的說明他們需要輸入密碼。註冊過程是由照顧我的專案中的預設帳戶控制器。我需要創建承載這一課的頁面內容和編寫所需的學生參加在類中的代碼。為學生加入教室一類處於活動狀態時,他們必須先報名參加該課程。

構建課堂控制器控制器中的專案的根資料夾上按右鍵讓我添加一個新的控制器並命名為 ClassroomController。我向此類添加的兩個主要方法是的指數,在那裡將送達的主要內容和 GetModuleStep,滿足一些先決條件後返回請求的步驟。第三個操作處理情況下那裡有沒有積極的類別模組。若要訪問模組材料,必須登錄到該網站並報名參加了活動模組課程學生。

允許課程招生 ClassroomController 是德科­額定與我創建,以確保學生只能訪問的課程,他們須由教師設置的輸入代碼 EnrollmentVerficationFilter。如果還沒有尚未註冊使用者或教練還沒有開始一個模組,然後學生被重定向到索引行動上 EnrollmentController,正如你可以看到在圖 7。學生可以報讀的課程用適當的條目的代碼。後成功註冊,添加索賠使用有關ASP.NET標識元件的使用者帳戶。


圖 7 課程大廳和註冊頁

我添加通過 UserManager 類,到的訪問通過獲取我的 ApplicationDbCoNtext 的一個實例並使用,生成 UserStore,然後傳遞到我的目標類索賠:

var context = new ApplicationDbContext();
var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore);

一旦我在的地方有必要元件,我通過校長代表他的身份得到使用者的 ID,生成一個索賠物件。 然後我將,添加到該使用者的帳戶:

var userId = User.Identity.GetUserId();
var courseClaim = new Claim(MvcApplication.CourseRegistrationClaimUrn,
  enroll.CourseId.ToString(CultureInfo.InvariantCulture));
userManager.AddClaim(userId, courseClaim);

在地方上的使用者帳戶的索賠,一個學生可能現在訪問教室。

檢查教室視圖 正如你可以看到在 圖 8,教室分為兩個部分。頁面的頂部為當前模組的概述並提供控制項以跳轉到任何可用的步驟。底部所謂的黑板上,並顯示由講師的共用內容。


圖 8 虛擬黑板

這頁真的僅有幾個 DIV 元素作為內容的容器。其餘是通過 JavaScript 了有線和通過內容獲取基於來自 ClassroomHub 或學生的選擇上一步的消息。教練選擇新的步驟,ClassroomHub 通知,並將信號發送到所有人都在教室裡。這反過來提取資料從 ClassroomController,因此啟用緩存。

部署專案

講師可以創建和管理課程、 模組和步驟。學生可以為網站登記和註冊自己的課程。課程都通過招生的要求,保護和虛擬教室的黑板用的內容更新,由授課老師的指導。船的時間啊 !

從生成功能表中,選擇要發佈我的專案的選項。將顯示發佈 Web 對話方塊,然後 Azure 網站作為發佈目標。Visual Studio提示我輸入我的憑據如果我已經沒在簽署。然後我可以選擇我在開始這個專案時創建的現有網站。我發佈的設定檔是然後下載,完成與預配置的資料庫連接字串並將我的網站發送到 Azure 所需的所有憑據。

在這個專案的開始,第一次準備好我的網站在 Azure 門戶中。因為這個專案使用 DefaultConnection 連接字串,已經存在於我的發佈設定檔,我不需要進行任何更改,當我去生產。生產連接字串自動點我的應用程式在以前配置 SQL Azure 資料庫。

利用 Azure 的 Web 網站

發佈一個網站到一個預先配置的終結點中 Azure 網站是一個受歡迎的驚喜。這是實際上很容易。經過多年的倖存的要複雜得多的部署步驟,這必然是一種享受。獨自一人,這不是結束遊戲為 Azure 網站。有很多工具可用:

  • 添加一個自訂的域:如果你可以註冊一個功能變數名稱,並設置了幾個 DNS 記錄,只需分鐘要添加到您的網站選擇的唯一的域。更多關於這在 bit.ly/1sV8R1y
  • 安全的應用程式:基於 SNI 的證書都負擔得起­能,和你可以通過儀表板的 Azure Web 網站添加它們。更多關於這在 bit.ly/1mYXndJ
  • 規模的網站:如果您發現您的專案正在增長,您可以選擇要擴大規模 (更強大的硬體) 或縮小 (更多實例)。Don忘了還配置 Azure 服務匯流排來處理你的那麼 SignalR 流量。瞭解更多,那麼 SignalR bit.ly/1o6B7AC
  • 添加連續部署:即使是最小的專案,我放棄直接部署和使用基於 Git 的原始程式碼管理伺服器。Azure 然後創建階段和自動部署我的網站上檢查中。更多關於這在 bit.ly/1o6BACT
  • 添加監視和警報:它是最好的知道什麼時候的東西不會完全正確在您的應用程式。你可以監視某些類型的問題並得到通知,因為他們發生,所有已配置的從你的網站的儀表板。

總結

在本文中,我使用了ASP.NET身份 2.0,現在是在Visual Studio2013年的預設ASP.NETMVC 範本的一部分。若要瞭解有關增強和更改的詳細資訊,請查閱的.NET Web 開發和工具的博客帖子 bit.ly/PXgQ2d。我還用那麼 SignalR,使用戶端和伺服器之間的即時通信。這會自動生成 JavaScript 代理,並且調用代碼在伺服器從用戶端,反之亦然。更多關於您的資料使用創建模型 EF 代碼優先ASP.NETMVC 5 應用程式中,訪問在教程 bit.ly/1pivbmE

豐富的經驗,是很容易提供當你不需要去關心底層的基礎架構或部署的複雜性。FrontClass 應用程式利用身份驗證、 授權、 即時消息的發送和持久性資料存儲。作為開發人員,我得到很多這些積木等其他人的努力。我不需要擔心其他運動部件,當我移動我的專案投入生產。

James Chambers* ASP.NET/IIS 和頻繁演講者在會議和使用者組的 Microsoft MVP 是加拿大各地。 他是作者的"Windows Azure 網站"(Wrox,2013年),可通過電子書 (bit.ly/wawsbook),並提出了關於微軟虛擬學院 (bit.ly/wawsmva)。他的博客 jameschambers.com 和你能聯繫到他在 Twitter 上 twitter.com/CanadianJames。*

由於以下的技術專家對本文的審閱:乍得麥卡勒姆 (獨立顧問)