.NET Core 3.0 Preview 3 已经推出, 它包含了一系列关于 ASP.NET Core 的新的更新.
下面是该预览版的更新列表:
Razor 组件改进:
单项目模板
新的 Razer 扩展
Endpoint 路由集成
预呈现
Razor 类库中的 Razor 组件
改进事件处理
Forms & validation
运行时编译
Worker 服务模板
gRPC 模板
Angular 模板已更新为 Angular 7
SPA 认证
SignalR 与 Endpoint 路由集成
SignalR Java 客户端支持长轮询
其他详细信息和已知问题, 请参阅发行说明 https://aka.ms/netcore3releasenotes .
开始
要在. NET Core 3.0 Preview 3 中开始使用 ASP.NET Core, 请安装. NET Core 3.0 Preview 3 SDK https://aka.ms/netcore3download
如果您使用的是 Visual Studio, 则还需要安装 Visual Studio 2019 的最新预览版 https://visualstudio.com/preview [译者注: 目前 VS2019 正式版已经发布, 直接安装正式版即可] .
注意: 要在 Visual Studio 2019 中使用. NET Core 3.0 预览版, 需要启用选项以使用. NET Core SDK 预览版, 方法是通过 [工具> 选项>项目和解决方案> .NET Core > 使用. NET Core SDK 预览版]
升级现有项目
将现有的 ASP.NET Core 应用程序升级到. NET Core 3.0 Preview 3, 请按照 ASP.NET Core 文档中的迁移步骤进行操作.
另请参阅 ASP.NET Core 3.0 中的重大更改的完整列表.
Razor 组件改进
在前面的预览中, 我们介绍了 Razor 组件, 这是一种用 ASP.NET 核心构建交互式客户端 web UI 的新方法. 本节将会介绍我们在该预览更新中对 Razor 组件所做的各种改进.
单项目模板
Razor 组件项目模板现在是单个项目, 而不是同一解决方案中的两个项目. 所编写的 Razor 组件位于托管它们的 ASP.NET Core 应用程序中. 同一个 ASP.NET Core 项目可以包含 Razor 组件, 页面和视图. Razor 组件模板与其他 ASP.NET Core Web 应用程序模板一样, 默认情况下也启用了 HTTPS.
新的 Razer 扩展
Razor 组件使用 Razor 语法编写, 但编译方式与 Razor 页面和视图不同. 为了明确哪些 Razor 文件应该编译为 Razor 组件, 我们引入了一个新的文件扩展名:.razor. 在 Razor 组件模板中, 所有组件文件现在都使用. razor 扩展名. Razor 页面和视图仍然使用. cshtml 扩展名.
只要使用_RazorComponentInclude MSBuild 属性将这些文件标识为 Razor 组件文件, Razor 组件仍然可以使用. cshtml 文件扩展名来创建. 例如, 该版本中的 Razor 组件模板指定 Components 文件夹下的所有. cshtml 文件为 Razor 组件.
1: <_RazorComponentInclude>Components\**\*.cshtml</_RazorComponentInclude>
请注意, 这个版本中的. razor 文件有很多限制. 有关已知问题和可用解决方案的列表, 请参考发布说明.
Endpoint 路由集成
Razor 组件现在已经集成到了 ASP.NET Core 中新的 Endpoint 路由系统. 要在应用程序中启用 Razor 组件支持, 需要在路由配置中使用 MapComponentHub<TComponent>.
- App.UseRouting(routes =>
- {
- routes.MapRazorPages();
- routes.MapComponentHub<App>("app");
这会将应用程序配置以接受交互式 Razor 组件的传入连接, 并指定根组件 App 应该在匹配选择器 App 的 DOM 元素中呈现.
预呈现
默认情况下, Razor 组件项目模板执行服务端预渲染. 也就是说当用户浏览您的应用程序时, 服务器将对您的 Razor 组件执行初始化渲染, 并将结果作为纯静态 HTML 传递给浏览器. 然后, 浏览器将通过 SignalR 重新连接到服务器, 并将 Razor 组件切换为完全交互的模式. 这两个阶段的交付是有益的, 因为:
它提高了站点的感知能力, 因为用户界面可以更快地出现, 而无需等待进行任何 WebSocket 连接, 甚至运行任何客户端脚本. 这对连接速度较慢的用户有着更大的影响, 如 2G/3G 手机.
它可以让搜索引擎很容易的搜索到你的应用程序.
对于使用更快连接的用户(如内网用户), 此功能的影响较小, 因为无论如何用户界面都应该立即出现.
设置预渲染, 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 组件添加到 Razor 类库中, 并使用 Razor 组件从 ASP.NET 核心项目引用它们.
在 Razer 类库中创建可重用的 Razer 组件:
1, 创建 Razer 组件应用程序
1: dotnet new razorcomponents -o RazorComponentsApp1
2, 创建 Razer 类库
1: dotnet new razorclasslib -o RazorClassLib1
3, 添加 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:
- }
1, 使用 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:
- }
- UsesMyButton.razor
- 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.
Forms&validation
此预览版本添加了用于处理表单和验证的内置组件和基础结构.
使用. net 进行客户端 Web 开发的一个好处是能够在客户端和服务器之间共享相同的实现逻辑. 验证逻辑是一个很好的逻辑. Razor 组件中的新的 Forms&validation 支持包括使用数据注解处理验证的支持, 或者可以插入你喜欢的验证系统.
例如, 以下 Person 类型使用数据注解定义验证逻辑:
- public class Person
- {
- [Required(ErrorMessage = "Enter a name")]
- [StringLength(10, ErrorMessage = "That name is too long")]
- public string Name { get; set; }
- [Range(0, 200, ErrorMessage = "Nobody is that old")]
- public int AgeInYears { get; set; }
- [Required]
- [Range(typeof(bool), "true", "true", ErrorMessage = "Must accept terms")]
- public bool AcceptsTerms { get; set; }
- }
以下是如何基于 Person 模型锁创建的验证表单:
- <EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
- <DataAnnotationsValidator />
- <ValidationSummary />
- <p class="name">
- Name: <InputText bind-Value="@person.Name" />
- </p>
- <p class="age">
- Age (years): <InputNumber bind-Value="@person.AgeInYears" />
- </p>
- <p class="accepts-terms">
- Accepts terms: <InputCheckbox bind-Value="@person.AcceptsTerms" />
- </p> 14:
- <button type="submit">Submit</button>
- </EditForm> 17: 18: @functions {
- Person person = new Person();
- void HandleValidSubmit()
- {
- Console.WriteLine("OnValidSubmit");
- } 25: }
如果将此表单添加到应用程序中, 并运行它, 你将获得一个基本表单, 该表单在字段更改和表单提交时自动进行字段输入值的验证.
这里发生了很多事情, 让我们把它一个一个地分解:
这个表单是使用新的 EditForm 组件定义的. EditForm 将 EditContext 设置为一个级联相关的值, 该值用于跟踪关于编辑过程的元数据 (例如, 已修改的内容, 当前验证消息等).EditForm 还为有效和无效提交(OnValidSubmit,OnInvalidSubmit) 提供了合适的事件. 如果想自己触发验证, 也可以直接使用 OnSubmit.
DataAnnotationsValidator 组件使用数据注解, 以验证支持附加到级联的 EditContext. 使用数据注释启用验证支持需要显式调用, 但我们正在考虑将其作为默认行为, 但随后你可以覆盖它.
每个表单字段都是使用一组内置的输入组件 (InputText, InputNumber, InputCheckbox, InputSelect 等) 定义的. 这些组件提供默认行为, 用于在编辑时验证并更改它们的 CSS 类以反映字段状态. 其中一些具有有用的分析逻辑(例如, InputDate 和 InputNumber 将不可解析的值注册为验证错误, 这样可以优雅地处理它们). 相关字段还支持目标字段的可空性(例如, int?).
ValidationMessage 组件显示特定字段的验证消息.
ValidationSummary 组件汇总所有验证消息(类似于验证摘要标记助手).
内置的输入组件存在一些限制, 我们希望在将来的更新中改进这些限制. 例如, 目前不能在生成输入标记上指定任意属性. 将来, 我们计划启用组件的所有额外属性. 现在, 您需要构建自己的组件子类来处理这些情况.
运行时验证
对运行时编译的支持已从. 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();
Worker 服务模板
在 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
Angular 模板更新到了 Angular 7. 在 .NET Core 3.0 发布稳定版本之前, 我们预计会更新到 Angular 8.
SPA 身份认证
这个版本, 在 Angular 和 React 模板中引入了对身份验证的支持. 在本节中, 我们将展示如何创建一个新的 Angular 或 React 模板, 该模板允许我们对用户进行身份验证并访问受保护的 API 资源.
我们对用户身份验证和授权的支持是由 IdentityServer 在后台提供的, 我们构建了一些扩展来简化我们特定场景的配置体验.
注意: 在本文中, 我们展示了对 Angular 的身份验证支持, 但在 React 模板中提供了相同的功能.
创建新的 Angular 应用程序
要创建一一个新的支持身份验证的 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
如果我们点击获取数据, 我们可以看到天气预报数据列表
保护现有的 API
要保护服务器上的 API, 只需要在要保护的控制器或操作上使用 [Authorize] 属性.
- [Authorize]
- [Route("api/[controller]")]
- public class SampleDataController : Controller
- { 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 {
- }
带有 SignalR Hubs 的 Endpoint 路由
在 preview3 中, 我们将 SignalR hubs 连接到最近发布的新端点路由特性中. SignalR hub 连线之前已经明确完成:
- App.UseSignalR(routes =>
- {
- routes.MapHub<ChatHub>("hubs/chat");
- });
这意味着开发人员需要在启动期间将控制器, 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 中一站式地路由几乎所有内容.
- App.UseRouting(routes =>
- {
- routes.MapRazorPages();
- routes.MapHub<ChatHub>("hubs/chat");
- });
Java SignalR 客户端的长轮询
我们向 Java 客户端添加了长轮询支持, 这使它能够在不支持 WebSockets 的环境中建立连接. 这也使您能够在客户端应用程序中专门选择长轮询传输.
gRPC 模板
这个预览版引入了一个用 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 上的 https://github.com/grpc/grpc-dotnet/issues 上给我们反馈.
未来将会有更详细地讨论 ASP.NET Core 使用 gRPC 的博客文章, 请继续关注.
反馈
我们希望您喜欢这个预览版的 ASP.NET Core 中的新功能! 请通过在 GitHub 上提交问题让我们知道你的想法.
来源: https://www.cnblogs.com/edison0621/p/10714069.html