【译】.NET Core 3.0 Preview 3中关于ASP.NET Core的更新内容
.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客户端支持长轮询
其他详细信息和已知问题,请参阅发行说明。
开始
要在.NET Core 3.0 Preview 3中开始使用ASP.NET Core,请安装.NET Core 3.0 Preview 3 SDK
如果您使用的是Visual Studio,则还需要安装Visual Studio 2019的最新预览版【译者注:目前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>。
1: app.UseRouting(routes =>
2: {
3: routes.MapRazorPages();
4: 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: }
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类型使用数据注解定义验证逻辑:
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: }
如果将此表单添加到应用程序中,并运行它,你将获得一个基本表单,该表单在字段更改和表单提交时自动进行字段输入值的验证。
这里发生了很多事情,让我们把它一个一个地分解:
- 这个表单是使用新的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]属性。
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 { }
带有SignalR Hubs的Endpoint路由
在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 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上的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/
【译】.NET Core 3.0 Preview 3中关于ASP.NET Core的更新内容的更多相关文章
- .NET Core 3.0 Preview 6中对ASP.NET Core和Blazor的更新
我们都知道在6月12日的时候微软发布了.NET Core 3.0的第6个预览版.针对.NET Core 3.0的发布我们国内的微软MVP-汪宇杰还发布的官翻版的博文进行了详细的介绍.具体的可以关注&q ...
- .NET 5 Preview 1中的ASP.NET Core更新 (2020年3月16日)
.NET 5 Preview1现在可用,可以进行评估了! .NET 5将是当前版本. 开始 要在.NET 5.0中开始使用 ASP.NET Core,请安装.NET 5.0 SDK. 如果您使用的是W ...
- 探索ASP.Net Core 3.0系列四:在ASP.NET Core 3.0的应用中启动时运行异步任务
前言:在本文中,我将介绍ASP.NET Core 3.0 WebHost的微小更改如何使使用IHostedService在应用程序启动时更轻松地运行异步任务. 翻译 :Andrew Lock ht ...
- 探索ASP.Net Core 3.0系列二:聊聊ASP.Net Core 3.0 中的Startup.cs
原文:探索ASP.Net Core 3.0系列二:聊聊ASP.Net Core 3.0 中的Startup.cs 前言:.NET Core 3.0 SDK包含比以前版本更多的现成模板. 在本文中,我将 ...
- ASP.NET Core 2.0 Preview 1 中贴心的新特性
西雅图时间5月10日,微软在 Build 2017 大会上发布了 ASP.NET Core 2.0 Preview 1 ( 详见 Announcing ASP.NET 2.0.0-Preview1 a ...
- ASP.NET Core在 .NET Core 3.1 Preview 1中的更新
.NET Core 3.1 Preview 1现在可用.此版本主要侧重于错误修复,但同时也包含一些新功能. 这是此版本的ASP.NET Core的新增功能: 对Razor components的部分类 ...
- .NET Core 2.0 Preview 1发布下载和文档
.NET Core 2.0.0 Preview 1 发布于 2017 5.10. 你可以通过 Visual Studio 2017 Preview 15.3, Visual Studio for Ma ...
- [翻译] .NET Core 3.0 Preview 7 发布
原文: Announcing .NET Core 3.0 Preview 7 今天,我们宣布推出 .NET Core 3.0 Preview 7 .我们的工作已经从创建新功能过渡到打磨版本.预计剩余的 ...
- .NET Core 3.0预览版7中的ASP.NET Core和Blazor更新
.NET Core 3.0 Preview 7现已推出,它包含一系列ASP.NET Core和Blazor的新更新. 以下是此预览中的新功能列表: 最新的Visual Studio预览包括.NET C ...
随机推荐
- linux系统日志查看
系统 日志文件( 可以通过cat 或tail 命令来查看) /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一/var/log/secure ...
- python获取当前时间
import time time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()) print("当前时间:",time) ...
- (5)STM32使用HAL库实现串口通讯——实战操作
功能需求: (1)对接收的字符串原样返回(每10个字符一次). (2)发送一个字符串完成后改变LED的状态. 1.创建工程 使用的是F407Discovery,4个LED对应PD12-PD14. (1 ...
- 发现了一个非常棒的pyqt5的例子集
发现了一个非常棒的pyqt5的例子集 https://github.com/892768447/PyQt 各种各样的PyQt测试和例子 [Python3.4.4 or Python3.5][PyQt5 ...
- ASP.NET Core 实战:构建带有版本控制的 API 接口
一.前言 在上一篇的文章中,主要是搭建了我们的开发环境,同时创建了我们的项目模板框架.在整个前后端分离的项目中,后端的 API 接口至关重要,它是前端与后端之间进行沟通的媒介,如何构建一个 “好用” ...
- 理解 KMP 算法
KMP(The Knuth-Morris-Pratt Algorithm)算法用于字符串匹配,从字符串中找出给定的子字符串.但它并不是很好理解和掌握.而理解它概念中的部分匹配表,是理解 KMP 算法的 ...
- Java线程状态间的互相转换
ava中线程的状态分为6种. 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法. 2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running) ...
- 关于elementUi tab组件路由跳转卡死问题
好久没来了,周五项目终于要上线了(*^▽^*),上线之前测出一个很恶心的bug真真是... 项目:Vue + elementUi 后台管理项目 问题描述:登录后首次通过侧边栏路由跳转到主页面有ta ...
- 全球第一免费开源ERP Odoo PM OKR项目管理操作指南
概览 Odoo项目允许你和整个项目团队一起管理项目, 与项目和任务成员中的任何一个人沟通. 它与包含可定制阶段的任务的项目一起工作.项目可以是内部的或客户导向的.任务是项目执行的一部分.你可以给这 ...
- bootStrap-table服务器端后台分页的使用,以及自定义搜索框的实现,前端代码到数据查询超详细讲解
关于分页,之前一直纯手写js代码来实现,最近又需要用到分页,找了好多最终确定bootstrap-table,正好前端页面用的是bootstrap. 首先下载BootStrap-table的js和CSS ...