.NET Core 3.0 Preview 3已經推出,它包含了一系列關於ASP.NET Core的新的更新。html
下面是該預覽版的更新列表:git
其餘詳細信息和已知問題,請參閱發行說明。github
要在.NET Core 3.0 Preview 3中開始使用ASP.NET Core,請安裝.NET Core 3.0 Preview 3 SDKweb
若是您使用的是Visual Studio,則還須要安裝Visual Studio 2019的最新預覽版【譯者注:目前VS2019正式版已經發布,直接安裝正式版便可】。數據庫
將現有的ASP.NET Core應用程序升級到.NET Core 3.0 Preview 3,請按照ASP.NET Core文檔中的遷移步驟進行操做。bootstrap
另請參閱ASP.NET Core 3.0 中的重大更改的完整列表。api
在前面的預覽中,咱們介紹了Razor組件,這是一種用ASP.NET核心構建交互式客戶端Web UI的新方法。本節將會介紹咱們在該預覽更新中對Razor組件所作的各類改進。瀏覽器
Razor組件項目模板如今是單個項目,而不是同一解決方案中的兩個項目。所編寫的Razor組件位於託管它們的ASP.NET Core應用程序中。同一個ASP.NET Core項目能夠包含Razor組件、頁面和視圖。Razor組件模板與其餘ASP.NET Core Web應用程序模板同樣,默認狀況下也啓用了HTTPS。服務器
Razor組件使用Razor語法編寫,但編譯方式與Razor頁面和視圖不一樣。爲了明確哪些Razor文件應該編譯爲Razor組件,咱們引入了一個新的文件擴展名:.razor。在Razor組件模板中,全部組件文件如今都使用.razor擴展名。Razor頁面和視圖仍然使用.cshtml擴展名。app
只要使用_RazorComponentInclude MSBuild屬性將這些文件標識爲Razor組件文件,Razor組件仍然可使用.cshtml文件擴展名來建立。例如,該版本中的Razor組件模板指定Components文件夾下的全部.cshtml文件爲Razor組件。
1: <_RazorComponentInclude>Components\**\*.cshtml</_RazorComponentInclude>
請注意,這個版本中的.razor文件有不少限制。有關已知問題和可用解決方案的列表,請參考發佈說明。
Razor組件如今已經集成到了ASP.NET Core中新的Endpoint路由系統。要在應用程序中啓用Razor組件支持,須要在路由配置中使用MapComponentHub<TComponent>。
1: app.UseRouting(routes =>
2: {
3: routes.MapRazorPages();
4: routes.MapComponentHub<App>("app");
這會將應用程序配置以接受交互式Razor組件的傳入鏈接,並指定根組件App應該在匹配選擇器App的DOM元素中呈現。
默認狀況下,Razor組件項目模板執行服務端預渲染。也就是說當用戶瀏覽您的應用程序時,服務器將對您的Razor組件執行初始化渲染,並將結果做爲純靜態HTML傳遞給瀏覽器。而後,瀏覽器將經過SignalR從新鏈接到服務器,並將Razor組件切換爲徹底交互的模式。這兩個階段的交付是有益的,由於:
對於使用更快鏈接的用戶(如內網用戶),此功能的影響較小,由於不管如何用戶界面都應該當即出現。
設置預渲染,Razor組件項目模板不會有靜態HTML文件。取而代之的是單個Razor頁面/Pages/Index.cshtml,使用Html.RenderComponentAsync<TComponent>() HTML幫助器預呈現應用程序內容。該頁面還引用components.server.js腳本,在預呈現和下載內容後設置SignalR 鏈接。因爲這是一個Razor頁面,像環境標籤助手這樣的功能就能夠工做了。
Index.cshtml
1: @page "{*clientPath}"
2: <!DOCTYPE html>
3: <html>
4: <head>
5: ...
6: </head>
7: <body>
8: <app>@(await Html.RenderComponentAsync<App>())</app>
9:
10: <script src="_framework/components.server.js"></script>
11: </body>
12: </html>
除了應用程序加載速度更快以外,還能夠在瀏覽器開發工具中查看下載的HTML源代碼,從而能夠看到預渲染正在進行。Razor組件在HTML中是徹底呈現的。
如今能夠將Razor組件添加到Razor類庫中,並使用Razor組件從ASP.NET核心項目引用它們。
在Razer類庫中建立可重用的Razer組件:
一、建立Razer組件應用程序
1: dotnet new razorcomponents -o RazorComponentsApp1
二、建立Razer類庫
1: dotnet new razorclasslib -o RazorClassLib1
三、添加Component1.razor文件到Razer類庫
Component1.razor
1: <h1>Component1</h1>
2:
3: <p>@message</p>
4:
5: @functions {
6: string message = "Hello from a Razor Class Library"!;
7: }
一、使用Razor組件從ASP.NET Core應用程序引用Razor類庫
1: dotnet add RazorComponentsApp1 reference RazorClassLib1
在Razor組件應用程序中,使用@addTagHelper指令從Razor類庫導入全部組件,而後在應用程序中使用component1
Index.razor
1: @page "/"
2: @addTagHelper *, RazorClassLib1
3:
4: <h1>Hello, world!</h1>
5:
6: Welcome to your new app.
7:
8: <Component1 />
注意:在此版本中,Razer類庫與Blazor應用程序並不兼容。另外,Razor類庫還不支持靜態資源。若是要在庫中建立可與Blazor和Razor組件應用程序共享的組件,仍然須要使用Blazor類庫。這寫問題會在將來的更新中解決。
新的eventcallback和eventcallback<>類型使得定義組件回調更加簡單。例如,考慮如下兩個組件:
MyButton.razor
1: <button onclick="@OnClick">Click here and see what happens!</button>
2:
3: @functions {
4: [Parameter] EventCallback<UIMouseEventArgs> OnClick { get; set; }
5: }
1: <div>@text</div>
2:
3: <MyButton OnClick="ShowMessage" />
4:
5: @function {
6: string text;
7:
8: void ShowMessage(UIMouseEventArgs e)
9: {
10: text = "Hello, world!";
11: }
12: }
onclick回調的類型是EventCallback<UIMouseEventArgs>(取代Action<UIMouseEventArgs>),MyButton直接傳遞給onclick事件處理程序。編譯器處理將委託轉換爲EventCallback的過程,並將執行其餘一些操做,以確保呈現過程具備足夠的信息來呈現正確的目標組件。所以,不須要在ShowMessage事件處理程序中顯式調用StateHasChanged。編譯器處理將委託轉換爲EventCallback的過程,並將執行其餘一些操做,以確保渲染過程具備足夠的信息來渲染正確的目標組件。所以,不須要在ShowMessage事件處理程序中顯式調用StateHasChanged。
經過使用EventCallback<>類型的OnClick處理程序能夠是異步的,而不須要對MyButton進行任何其餘代碼的修改。
UsesMyButton.razor
1: <div>@text</div>
2:
3: <MyButton OnClick="ShowMessageAsync" />
4:
5: @function {
6: string text;
7:
8: async Task ShowMessageAsync(UIMouseEventArgs e)
9: {
10: await Task.Yield();
11: text = "Hello, world!";
12: }
13: }
咱們建議在爲事件處理和綁定定義組件參數時使用EventCallback and EventCallback<T>。儘量使用EventCallback<>,由於它是強類型的而且能夠向組件的用戶提供更好的反饋。當沒有傳遞給回調函數的值時,也使用EventCallback。
此預覽版本添加了用於處理表單和驗證的內置組件和基礎結構。
使用. net進行客戶端web開發的一個好處是可以在客戶端和服務器之間共享相同的實現邏輯。驗證邏輯是一個很好的邏輯。Razor組件中的新的Forms&validation支持包括使用數據註解處理驗證的支持,或者能夠插入你喜歡的驗證系統。
例如,如下Person類型使用數據註解定義驗證邏輯:
1: public class Person
2: {
3: [Required(ErrorMessage = "Enter a name")]
4: [StringLength(10, ErrorMessage = "That name is too long")]
5: public string Name { get; set; }
6:
7: [Range(0, 200, ErrorMessage = "Nobody is that old")]
8: public int AgeInYears { get; set; }
9:
10: [Required]
11: [Range(typeof(bool), "true", "true", ErrorMessage = "Must accept terms")]
12: public bool AcceptsTerms { get; set; }
13: }
如下是如何基於Person
模型鎖建立的驗證表單:
1: <EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
2: <DataAnnotationsValidator />
3: <ValidationSummary />
4:
5: <p class="name">
6: Name: <InputText bind-Value="@person.Name" />
7: </p>
8: <p class="age">
9: Age (years): <InputNumber bind-Value="@person.AgeInYears" />
10: </p>
11: <p class="accepts-terms">
12: Accepts terms: <InputCheckbox bind-Value="@person.AcceptsTerms" />
13: </p>
14:
15: <button type="submit">Submit</button>
16: </EditForm>
17:
18: @functions {
19: Person person = new Person();
20:
21: void HandleValidSubmit()
22: {
23: Console.WriteLine("OnValidSubmit");
24: }
25: }
若是將此表單添加到應用程序中,並運行它,你將得到一個基本表單,該表單在字段更改和表單提交時自動進行字段輸入值的驗證。
這裏發生了不少事情,讓咱們把它一個一個地分解:
內置的輸入組件存在一些限制,咱們但願在未來的更新中改進這些限制。例如,目前不能在生成輸入標記上指定任意屬性。未來,咱們計劃啓用組件的全部額外屬性。如今,您須要構建本身的組件子類來處理這些狀況。
對運行時編譯的支持已從.NET Core 3.0中的ASP.NET核心共享框架中刪除,但如今能夠經過嚮應用程序添加包的方式來啓用它。
啓用運行時編譯:
添加Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
1: <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.0.0-preview3-19153-02" />
在Startup.ConfigureServices添加對AddRazorRuntimeCompilation的調用
1: services.AddMvc().AddRazorRuntimeCompilation();
在preview3中,咱們引入了一個名爲「Worker Service」的新模板。此模板被設計爲運行長時間運行的後臺進程的起點,就像您可能做爲Windows服務或Linux守護進程運行同樣。例如,從消息隊列生成/消費消息,或者監視要處理的文件。它旨在支持ASP.NET Core的生產力功能,如日誌記錄,DI,配置等,而不承載任何Web依賴項。
在接下來的幾天裏,咱們將發佈一些博客文章,提供更多關於使用Worker模板入門的練習。咱們將有一些專門官微Windows/SystemD服務發佈、在ACI/AKS上運行以及做爲WebJob運行的文章。
雖然其目的是使工做模板默認狀況下不依賴於web技術,但在preview3中它仍然使用web SDK,並在您選擇「ASP.NET Core WebApplication」以後顯示出來。
Angular模板更新到了Angular 7。在 .NET Core 3.0 發佈穩定版本以前,咱們預計會更新到Angular 8。
這個版本,在Angular和React模板中引入了對身份驗證的支持。在本節中,咱們將展現如何建立一個新的Angular或React模板,該模板容許咱們對用戶進行身份驗證並訪問受保護的API資源。
咱們對用戶身份驗證和受權的支持是由IdentityServer在後臺提供的,咱們構建了一些擴展來簡化咱們特定場景的配置體驗。
注意:在本文中,咱們展現了對Angular的身份驗證支持,但在React模板中提供了相同的功能。
要建立一一個新的支持身份驗證的Angular應用程序,咱們須要調用如下命令:
1: dotnet new angular -au Individual
這個命令建立一個新的ASP.NET Core應用程序和託管的客戶端Angular應用程序。ASP.NET Core應用程序包括已配置的Identity Server實例,但是讓Angular應用程序很方面的對用戶進行身份驗證,並針對ASP.NET Core應用程序中的受保護資源發送HTTP請求。
Angular模塊所構建的身份驗證和受權支持,能夠導入到您的應用程序中,並提供一套組件和服務來加強主應用程序模塊的功能。
要運行應用程序,只需執行如下命令,而後用瀏覽器打開控制檯上顯示的URL:
1: dotnet run
1: Hosting environment: Development
2: Content root path: C:\angularapp
3: Now listening on: https://localhost:5001
4: Now listening on: http://localhost:5000
5: Application started. Press Ctrl+C to shut down.
運行結果以下:
當咱們打開應用程序時,咱們會看到經常使用的Home、Counter和Fetch數據菜單選項以及兩個新選項:Register和Login。若是單擊Register,咱們將被髮送到默認的認證界面(在運行遷移和更新數據庫以後),在那裏咱們能夠註冊爲新用戶。
註冊爲新用戶後,咱們將被重定向迴應用程序,在那裏咱們能夠看到咱們成功地經過了身份驗證。
若是咱們點擊獲取數據,咱們能夠看到天氣預報數據列表
要保護服務器上的API,只須要在要保護的控制器或操做上使用[Authorize]屬性。
1: [Authorize]
2: [Route("api/[controller]")]
3: public class SampleDataController : Controller
4: {
5: ...
6: }
爲了在Angular應用程序訪問頁面時,要求對用戶進行身份驗證,咱們將[AuthorizeGuard]應用到正在配置的路由上。
1: import { ApiAuthorizationModule } from 'src/api-authorization/api-authorization.module';
2: import { AuthorizeGuard } from 'src/api-authorization/authorize.guard';
3: import { AuthorizeInterceptor } from 'src/api-authorization/authorize.interceptor';
4:
5: @NgModule({
6: declarations: [
7: AppComponent,
8: NavMenuComponent,
9: HomeComponent,
10: CounterComponent,
11: FetchDataComponent
12: ],
13: imports: [
14: BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
15: HttpClientModule,
16: FormsModule,
17: ApiAuthorizationModule,
18: RouterModule.forRoot([
19: { path: '', component: HomeComponent, pathMatch: 'full' },
20: { path: 'counter', component: CounterComponent },
21: { path: 'fetch-data', component: FetchDataComponent, canActivate: [AuthorizeGuard] },
22: ])
23: ],
24: providers: [
25: { provide: HTTP_INTERCEPTORS, useClass: AuthorizeInterceptor, multi: true }
26: ],
27: bootstrap: [AppComponent]
28: })
29: export class AppModule { }
在preview3中,咱們將SignalR hubs鏈接到最近發佈的新端點路由特性中。SignalR hub連線以前已經明確完成:
1: app.UseSignalR(routes =>
2: {
3: routes.MapHub<ChatHub>("hubs/chat");
4: });
這意味着開發人員須要在啓動期間將控制器、Razor頁面和hubs鏈接到不一樣的位置,從而產生一系列幾乎相同的路由片斷:
1: app.UseSignalR(routes =>
2: {
3: routes.MapHub<ChatHub>("hubs/chat");
4: });
5:
6: app.UseRouting(routes =>
7: {
8: routes.MapRazorPages();
9: });
如今,SignalR hub也能夠經過endpoint路由進行路由分發,所以您能夠在ASP.NET Core中一站式地路由幾乎全部內容。
1: app.UseRouting(routes =>
2: {
3: routes.MapRazorPages();
4: routes.MapHub<ChatHub>("hubs/chat");
5: });
咱們向Java客戶端添加了長輪詢支持,這使它可以在不支持WebSockets的環境中創建鏈接。這也使您可以在客戶端應用程序中專門選擇長輪詢傳輸。
這個預覽版引入了一個用ASP.NET Core構建的gRPC服務的新模板。NET Core使用一個新的gRPC框架,咱們正在與谷歌合做構建。
gRPC是一個流行的RPC(遠程過程調用)框架,它爲API開發提供了一種固定的契約優先方法。它使用HTTP/2進行傳輸,協議緩衝區做爲接口描述語言,並提供諸如身份驗證、雙向流和流控制、取消和超時等功能。
這些模板建立了兩個項目:一個是託管於ASP. NET Core中的gRPC服務,以及一個用於測試它的控制檯應用程序。
這是第一個爲ASP.NET Core公開發布的gRPC預覽,並無實現gRPC的全部功能,可是咱們正在努力使ASP.NET Core提供所提供得最佳的gRPC體驗成爲可能。請嘗試一下,並在GitHub上的grpc/grpc-dotnet上給咱們反饋。
將來將會有更詳細地討論ASP.NET Core使用gRPC的博客文章,請繼續關注。
咱們但願您喜歡這個預覽版的ASP.NET Core中的新功能!請經過在Github上提交問題讓咱們知道你的想法。
原文地址:https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-3/