.NET 5 Release Candidate(RC1)版本現在可以進行使用了,以下是發布的新功能:
- Blazor WebAssembly性能改進
- Blazor組件虛擬化
- Blazor WebAssembly預渲染
- Blazor WebAssembly的瀏覽器兼容性分析器
- Blazor JavaScript隔離和對象引用
- Blazor文件輸入支持
- Blazor中的自定義驗證類屬性
- Blazor對ontogle事件的支持
- 模型綁定DateTime為UTC
- 控制Startup類的激活
- ASP.NET Core API項目中的默認開放式API規范(Swagger)
- ASP.NET Core API項目提供更好的F5體驗
- SignalR並行集線器調用
- 在SignalR Java客戶端中添加了對Messagepack支持
- Kestrel終端可進行特定的選項配置
Get started
如果要在.NET 5 RC1中使用ASP.NET Core我們需要安裝.NET5 SDK。.NET RC1也包含了在Visual Studio 2019 16.8 Preview 3中。
我們需要使用Visual Studio 2019 16.8 Preview 3或者更高的版本才能使用.NET5 RC1。最新的Mac版Visual Studio預覽版也支持.NET5。要將.NET 5與Visual Studio Code一起使用,請安裝最新版本的C#擴展。
Upgrade an existing project
ASP.NET Core應用從.NET5 preview8升級到.NET5 RC1,可以通過如下步驟來升級:
- 將所有Microsoft.AspNetCore.包引用更新為5.0.0-rc.1.
- 如果使用的是新的Microsoft.AspNetCore.Components.Web.Extensions程序包,需要更新版本到
5.0.0-preview.9.*
。目前這個包還有RC版本,因為開發團隊希望在准備發布之前對它包含的組件進行更多的設計和更改。
- 如果使用的是新的Microsoft.AspNetCore.Components.Web.Extensions程序包,需要更新版本到
- 將所有Microsoft.Extensions.程序包引用更新為5.0.0-rc.1.
- 將System.Net.Http.Json包引用更新為5.0.0-rc.1.*
在Blazor WebAssembly項目中,還可以對項目文件進行如下的更新:
- 將SDK從
Microsoft.NET.Sdk.Web
修改為Microsoft.NET.Sdk.BlazorWebAssembly
- 刪除
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
和<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
屬性
What’s new?
Blazor WebAssembly performance improvements
對於.NET5開發團隊已經對Blazor WebAssembly運行時性能進行了重大的改進,特別是對於復雜的UI和JSON序列化,在開發團隊的性能測試中,據了解在大多數情況下,Blazor WebAssembly在.NET5中速度要快2-3倍。
.NET5中的Blazor WebAssembly中的運行時代碼執行通常比Blazor WebAssembly3.2快,這是由於核心框架的優化和.NET IL解釋器的改進,在.NET5 WebAssembly中,如字符串比較,字典查找和JSON處理之類的操作通常要快很多。
如下圖所示,在.NET5中WebAssembly JSON的處理幾乎快了一倍:
開發團隊還優化了Blazor組件渲染的性能,尤其是對於涉及大量組件的UI,例如使用高密度grids時。
為了測試.NET5中grid組件呈現的性能,開發團隊使用了三種不同的grid組件實現,每個實現呈現200行和20列:
- Fast Grid: 一個最小的,高度優化grid實現
- Plain Table: 一個最小的,但是沒有優化的grid實現
- Complex Grid: 一個最大的,沒有優化的grid實現,故意應用大量的Blazor特性,故意對渲染器造成不良影響。
從測試來看grid渲染在.NET5中grid的渲染速度快了2-3倍
我們可以在GitHub中找到這些性能測試的代碼
我們可以期待正在進行的工作來改善Blazor WebAssembly的性能。.NET團隊除了優化Blazor WebAssembly運行時和框架之外,還與瀏覽器實現者合作,以進一步加快WebAssembly的執行速度。對於.NET6開發團隊打算向WebAssembly提供對提前編譯(AoT)的支持,這將進一步提高性能。
Blazor component virtualization
我們可以使用新的內置虛擬化支持進一步提高組件呈現的性能。虛擬化是一種將UI呈現限制為當前可見的部分的技術,例如,當我們有一個包含許多行的長列表或表,但在任何給定時間只有一個小子集可見時。.NET 5中的Blazor添加了一個新的虛擬化組件,可以輕松地將虛擬化添加到組件中。
典型的基於列表或表的組件可能使用c# foreach循環來呈現列表中的每一項或表中的每一行,就像這樣:
@foreach (var employee in employees)
{
<tr>
<td>@employee.FirstName</td>
<td>@employee.LastName</td>
<td>@employee.JobTitle</td>
</tr>
}
如果列表增加到包含數千行,那么呈現它的可能需要一段時間,從而導致UI明顯的延遲行為。
相反我們可以用Virtualize組件替換foreach循環,該組件僅呈現當前可見的行。
<Virtualize Items="employees" Context="employee">
<tr>
<td>@employee.FirstName</td>
<td>@employee.LastName</td>
<td>@employee.JobTitle</td>
</tr>
</Virtualize>
Virtualize組件根據容器的高度和已渲染項目的大小來計算要渲染的items數量。
如果您不想將所有items都加載到內存中,則可以指定一個ItemsProvider,如下所示:
<Virtualize ItemsProvider="LoadEmployees" Context="employee">
<tr>
<td>@employee.FirstName</td>
<td>@employee.LastName</td>
<td>@employee.JobTitle</td>
</tr>
</Virtualize>
items提供者是一種委托方法,可以按需異步檢索請求的items。 Items提供程序會收到ItemsProviderRequest
,該請求指定從特定起始索引開始的所需Items數量。 然后,項目提供程序從數據庫或其他服務中檢索請求的items,並將它們作為ItemsProviderResult <TItem>
連同可用items總數一起返回。 items提供者可以選擇在每個請求中檢索items,或將其緩存以方便使用。
async ValueTask<ItemsProviderResult<Employee>> LoadEmployees(ItemsProviderRequest request)
{
var numEmployees = Math.Min(request.Count, totalEmployees - request.StartIndex);
var employees = await EmployeesService.GetEmployeesAsync(request.StartIndex, numEmployees, request.CancellationToken);
return new ItemsProviderResult<Employee>(employees, totalEmployees);
}
因為從遠程數據源請求items可能需要一些時間,所以我們還可以選擇渲染占位符,知道items數據可用為止。
<Virtualize ItemsProvider="LoadEmployees" Context="employee">
<ItemContent>
<tr>
<td>@employee.FirstName</td>
<td>@employee.LastName</td>
<td>@employee.JobTitle</td>
</tr>
</ItemContent>
<Placeholder>
<tr>
<td>Loading...</td>
</tr>
</Placeholder>
</Virtualize>
Blazor WebAssembly prerendering
組件標簽幫助器現在支持兩種額外的渲染模式預先從Blazor WebAssembly應用程序中呈現組件:
- WebAssemblyPrerendered: 將組件預渲染為靜態HTML,並包含Blazor WebAssembly應用程序的標記,以便以后在加載到瀏覽器中時使組件具有交互性
- WebAssembly: 渲染Blazor WebAssembly應用程序的標記,以便在加載到瀏覽器中時包含一個交互式組件。 該組件未呈現。 這個選項使在不同的
cshtml
頁面上呈現不同的Blazor WebAssembly組件更加容易。
要在Blazor WebAssembly應用中設置預渲染,請執行以下操作:
1.將Blazor WebAssembly應用程序托管在ASP.NET Core應用程序中。
2.將客戶端項目中的默認靜態index.html文件替換為服務器項目中的_Host.cshtml文件。
3.更新服務器啟動邏輯,以回退到_Host.cshtml而不是index.html(類似於Blazor Server模板的設置方式)。
4.更新_Host.cshtml以使用組件標簽助手來預渲染根App組件:
<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
如果參數是可序列化的,則在使用基於WebAssembly的呈現方式時,還可以將參數傳遞給組件標簽幫助器。 這些參數必須是可序列化的,以便可以將其傳輸到客戶端並用於在瀏覽器中初始化組件。 如果要進行預渲染,則還需要確保編寫了組件,以便它們可以在不訪問瀏覽器的情況下優雅地執行服務器端。
<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" param-IncrementAmount="10" />
除了改善Blazor WebAssembly應用程序加載時間之外,我們還可以使用帶有新渲染模式的component tag helper來在不同的頁面和視圖上添加多個組件,我們不需要將這些組件配置為應用程序的根組件,也不需要在頁面上添加我們自己的標記,框架會為我們處理這些。
Browser compatibility analyzer for Blazor WebAssembly
Blazor WebAssembly應用在.NET5中的目標是完整的.NET5 API,但是由於瀏覽器沙箱的限制,WebAssembly上並不是支持所有的.NET5 API。.NET 5現在包含了一個平台兼容性分析器,當你的應用程序使用了你的目標平台不支持的api時,它會警告你。對於Blazor WebAssembly應用程序,這意味着檢查瀏覽器是否支持api。
我們還沒有將所有的注釋添加到.NET 5的核心庫中,現在已經注釋了一些API(主要是Windows特定的API)
要啟用瀏覽器對庫的兼容性檢查,請在項目文件中添加瀏覽器作為受支持的平台(Blazor WebAssembly項目和Razor類庫項目為您完成這一任務)
<SupportedPlatform Include="browser" />
在創建庫時,我們可以通過應用UnsupportedOSPlatformAttribute來選擇性地指示瀏覽器中不支持某個特定的API
[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{
// ...
}
Blazor JavaScript isolation and object references
Blazor現在可以將JavaScript隔離為標准的JavaScript模塊。這有幾個好處
1.導入的JavaScript不再污染全局名稱空間。
2.庫和組件的使用者不再需要手動導入相關的JavaScript。
例如,以下JavaScript模塊導出一個簡單的JavaScript函數以顯示瀏覽器提示:
export function showPrompt(message) {
return prompt(message, 'Type anything here');
}
我們可以將這個JavaScript模塊作為一個靜態網絡資產(wwwroot/exampleJsInterop.js)添加到我們的.NET庫中,然后使用IJSRuntime
服務將該模塊導入到.NET代碼中。
var module = await jsRuntime.InvokeAsync<JSObjectReference>("import", "./_content/MyComponents/exampleJsInterop.js");
“import”標識符是專門用於導入JavaScript模塊的特殊標識符。我們可以使用穩定的靜態web資產路徑指定模塊 _content/[LIBRARY NAME]/[PATH UNDER WWWROOT]
.
IJSRuntime
將該模塊作為JSObjectReference
導入,該對象代表.NET代碼對JavaScript對象的引用。 然后,我們可以使用JSObjectReference
從模塊調用導出的JavaScript函數:
public async ValueTask<string> Prompt(string message)
{
return await module.InvokeAsync<string>("showPrompt", message);
}
JSObjectReference
極大地簡化了與JavaScript庫的交互,在這些庫中,您希望捕獲JavaScript對象引用,然后再從.NET調用它們的函數。
Blazor file input support
Blazor現在提供了一個InputFile
組件,用於處理文件上載,或更一般地說,是用於將瀏覽器文件數據讀取到.NET代碼中。
InputFile
組件呈現為一個文件類型的HTML輸入。默認情況下,用戶可以選擇單個文件,或者如果您添加了多個屬性,那么用戶可以同時提供多個文件。當用戶選擇一個或多個文件時,InputFile組件觸發一個OnChange
事件,並傳遞一個InputFileChangeEventArgs
,該InputFileChangeEventArgs
提供對所選文件列表的訪問以及關於每個文件的詳細信息。
<InputFile OnChange="OnInputFileChange" multiple />
<div class="image-list">
@foreach (var imageDataUrl in imageDataUrls)
{
<img src="@imageDataUrl" />
}
</div>
@code {
IList<string> imageDataUrls = new List<string>();
async Task OnInputFileChange(InputFileChangeEventArgs e)
{
var imageFiles = e.GetMultipleFiles();
var format = "image/png";
foreach (var imageFile in imageFiles)
{
var resizedImageFile = await imageFile.RequestImageFileAsync(format, 100, 100);
var buffer = new byte[resizedImageFile.Size];
await resizedImageFile.OpenReadStream().ReadAsync(buffer);
var imageDataUrl = $"data:{format};base64,{Convert.ToBase64String(buffer)}";
imageDataUrls.Add(imageDataUrl);
}
}
}
要從用戶選擇的文件中讀取數據,可以對該文件調用OpenReadStream
並從返回的流中讀取數據。在Blazor WebAssembly應用程序中,數據會直接流到瀏覽器中的.NET代碼中。在Blazor服務器應用程序中,當您從流中讀取文件數據時,文件數據將流化為服務器上的.NET代碼。如果您使用組件來接收圖像文件,Blazor還提供了一個RequestImageFileAsync
便利方法,用於在圖像數據流到。net應用程序之前,在瀏覽器的JavaScript運行時內調整圖像數據的大小。
Custom validation class attributes in Blazor
現在可以在Blazor中指定自定義驗證類名。這在與CSS框架(如Bootstrap)集成時非常有用。
要指定自定義驗證類名,請創建一個從FieldCssClassProvider派生的類,並在EditContext實例上設置它。
var editContext = new EditContext(model);
editContext.SetFieldCssClassProvider(new MyFieldClassProvider());
// ...
class MyFieldClassProvider : FieldCssClassProvider
{
public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
{
var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
return isValid ? "legit" : "totally-bogus";
}
}
Blazor support for ontoggle event
Blazor現在支持ontoggle事件:
<div>
@if (detailsExpanded)
{
<p>Read the details carefully!</p>
}
<details id="details-toggle" @ontoggle="OnToggle">
<summary>Summary</summary>
<p>Detailed content</p>
</details>
</div>
@code {
bool detailsExpanded;
string message { get; set; }
void OnToggle()
{
detailsExpanded = !detailsExpanded;
}
}
Model binding DateTime as UTC
ASP.NET Core中的模型綁定現在支持將UTC時間字符串正確綁定到DateTime。 如果請求包含UTC時間字符串(例如https://example.com/mycontroller/myaction?time=2019-06-14T02%3A30%3A04.0576719Z),則模型綁定將正確地將其綁定到UTC DateTime而無需 需要進一步定制。
Control Startup class activation
提供了一個額外的UseStartup重載,它允許您提供一個工廠方法來控制啟動類的激活。如果我們想要傳遞與主機一同初始化的其他啟動參數,這將非常有用。
public class Program
{
public static async Task Main(string[] args)
{
var logger = CreateLogger();
var host = Host.CreateDefaultBuilder()
.ConfigureWebHost(builder =>
{
builder.UseStartup(context => new Startup(logger));
})
.Build();
await host.RunAsync();
}
}
Open API Specification On-by-default
Open API規范是一種行業采用的約定,用於描述HTTP API並將它們集成到復雜的業務流程或與第三方進行集成。開放API得到了所有雲提供商和許多API注冊中心的廣泛支持,因此從其Web API中發布開放API文檔的開發人員有許多新的機會可以使用這些API。與開源項目Swashbuckle.AspNetCore維護人員合作。我們激動地宣布,我們很高興地宣布,RC1中的ASP.NET Core API模板預先連接了對Swashbuckle的NuGet依賴關系,Swashbuckle是一種流行的開源NuGet包,可動態發出Open API文檔。 Swashbuckle通過對您的API控制器進行自省並在運行時或在構建時使用Swashbuckle CLI生成Open API文檔來做到這一點。
在.NET 5 RC1中,運行dotnet new webapi
將導致默認啟用開放API輸出,但如果您希望禁用開放API,請使用dotnet new webapi——no-openapi true
。所有為Web API項目創建的.csproj文件都將附帶NuGet包引用。
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
</ItemGroup>
除了.csproj
文件中的NuGet包引用之外,我們還向Startup.cs
中激活開放API文檔生成的ConfigureServices
方法添加了代碼。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication1", Version = "v1" });
});
}
配置方法還預先連接到Swashbuckle中間件中。這將啟動文檔生成過程,並在開發模式下默認打開Swagger UI頁面。這樣,當我們發布到生產環境中時,開箱即用的體驗就不會意外地暴露我們的API描述。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication1 v1"));
}
// ...
}
Azure API Management Import
在ASP.NET Core API項目以這種方式連接到輸出開放API, Visual Studio 2019版本16.8 Preview 2.1的發布體驗將在發布流程中自動提供額外的步驟。使用Azure API管理的開發人員有機會在發布流期間自動將他們的API導入到Azure API管理中。
這一額外的發布步驟減少了HTTP API開發人員發布API並與Azure邏輯應用程序或PowerApps一起使用所需要執行的步驟。
Better F5 Experience for Web API Projects
通過默認啟用開放API,我們能夠顯著改善Web API開發人員的F5體驗。在.NET 5 RC1中,Web API模板是預先配置來加載Swagger UI頁面的。Swagger UI頁面不僅提供了我們為API添加的文檔,還允許我們通過單擊進行API測試。
SignalR parallel hub invocations
在.NET 5 RC1中,NET Core SignalR現在能夠處理並行集線器調用。您可以更改默認行為,並允許客戶端一次調用多個hub方法。
HubConnection hubConnection = HubConnectionBuilder.create("http://localhost:53353/MyHub")
.withHubProtocol(new MessagePackHubProtocol())
.build();
Added Messagepack support in SignalR Java client
我們推出了一個新的軟件包,com.microsoft.signalr.messagepack
,它將messagepack支持添加到SignalR java客戶機。要使用messagepack集線器協議,請向連接構建器添加. withhubprotocol
(new MessagePackHubProtocol())。
HubConnection hubConnection = HubConnectionBuilder.create("http://localhost:53353/MyHub")
.withHubProtocol(new MessagePackHubProtocol())
.build();
Kestrel endpoint-specific options via configuration
增加了對通過配置配置Kestrel的特定端點選項的支持。特定於終結點的配置包括所使用的Http協議、所使用的TLS協議、所選擇的證書和客戶機證書模式。
我們可以根據指定的服務器名稱配置所選擇的證書,作為客戶機指示的TLS協議的服務器名稱指示(SNI)擴展的一部分。Kestrel配置還支持主機名中的通配符前綴。
下面的示例向我們展示了如何使用配置文件指定特定於終結點的內容
{
"Kestrel": {
"Endpoints": {
"EndpointName": {
"Url": "https://*",
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": [ "Tls11", "Tls12"],
"Certificate": {
"Path": "testCert.pfx",
"Password": "testPassword"
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "testCert2.pfx",
"Password": "testPassword"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
}
}
}
原文:https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-5-release-candidate-1/