.NET 8 Preview 4 中的 ASP.NET Core 更新

news/2024/4/21 1:27:07/

作者:Daniel Roth - Principal Program Manager, ASP.NET
翻译:Alan Wang
排版:Alan Wang

.NET 8 Preview 4 现已可用,并包括了许多对 ASP.NET Core 的新改进。
以下是本预览版本中的新内容摘要:

  • Blazor
    • 使用 Blazor 组件进行流式渲染
    • 使用 Blazor SSR 处理表单提交
    • 在 Blazor 中路由到命名元素
    • Webcil 为 Blazor WebAssembly 应用程序打包
  • API 编写
    • minimal API 中表单绑定的扩展支持
    • API 项目模板包含 .http 文件
  • Native AOT
    • 编译时生成的 minimal API 的日志记录和异常处理
    • ASP.NET Core 顶级 API 注释以去除警告
    • 通过可配置的 HTTPS 支持缩小应用程序大小
    • Worker Service 模板更新
    • 在 slim builder 中配置的其他默认服务
    • API 模板 JSON 配置更改
    • 支持编译器生成的 IAsyncEnumerable 无法表达类型的 JSON 序列化
  • 认证和授权
    • 标识 API 端点
    • 改进使用 IAuthorizationRequirementData 的自定义认证策略的支持
  • ASP.NET Core metrics

更多有关 .NET 8 中 ASP.NET Core 的计划,请在 GitHub 中查看完整的 ASP.NET Core .NET 8 路线图。

开始

在 .NET 8 Preview 4 中开始 ASP.NET Core,请安装 .NET 8 SDK。
如果您在 Windows 上使用 Visual Studio,我们建议您安装最新的 Visual Studio 2022 preview。目前 Visual Studio for Mac 尚不支持 .NET 8 预览版。

升级现有项目

将现有 ASP.NET Core 应用从 .NET 8 Preview 3 升级到 .NET 8 Preview 4:

  • 将应用程序的目标框架更新为 net8.0
  • 将所有 Microsoft.AspNetCore.* 包引用更新为 8.0.0-preview.4.*
  • 将所有 Microsoft.Extensions.* 包引用更新为 8.0.0-preview.4.*

查看 .NET 8 中 ASP.NET Core 所有突破性改变的完整列表。

Blazor

使用 Blazor 组件进行流式渲染

在 .NET 8 中,使用 Blazor 进行服务器端渲染(SSR)时,您现在可以在响应流上流式传输内容更新。流式渲染可以改善服务器端渲染页面的用户体验,这些页面需要执行长时间运行的异步任务才能完全渲染。

例如,为了渲染页面,您可能需要进行长时间运行的数据库查询或 API 调用。通常,渲染页面的所有异步任务都必须在渲染的响应可以发送之前完成,这可能会导致页面延迟加载。流式渲染最初使用占位符内容渲染整个页面,同时执行异步操作。一旦异步操作完成,更新的内容将通过同一响应连接发送到客户端,然后由 Blazor 修补到 DOM 中。这种方法的好处在于应用程序的主要布局可以尽可能快地渲染,一旦内容准备好,页面就会更新。

要启用流式渲染,您首先需要添加新的 Blazor 脚本。

<script src="_framework/blazor.web.js" suppress-error="BL9992"></script>

注意,如果你正在将此脚本添加到 Blazor 组件(如布局组件)中,则需要添加 suppress-error="BL9992" 属性,以避免出现在组件中使用脚本标记的错误。
然后,要为特定组件启用流式渲染,请使用 [StreamRendering(true)] 属性。这通常使用 @attribute Razor 指令完成:

@page "/fetchdata"
@using BlazorSSR.Data
@inject WeatherForecastService ForecastService
@attribute [StreamRendering(true)]
<PageTitle>Weather forecast</PageTitle>
<h1>Weather forecast</h1>
@if (forecasts is null)
{<p><em>Loading...</em></p>
}
else
{// Render weather forecasts
}
@code {private string message;protected override async Task OnInitializedAsync(){forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));}
}

如今,组件不再需要等待任何异步任务即可使用占位符内容(“Loading…”)完成初始渲染。异步任务完成后,更新的内容被流式传输到响应,然后由 Blazor 修补到 DOM 中。
在这里插入图片描述

使用 Blazor SSR 处理表单提交

现在可以使用 Blazor 组件来处理服务器端渲染的表单提交。

要启用从服务器处理表单提交,首先需要使用 CascadingModelBinder 组件设置模型绑定上下文。一个简单的方法是在应用程序的主布局中:

<CascadingModelBinder>@Body
</CascadingModelBinder>

要在 Blazor 中定义一个表单,可以使用现有的 EditForm 组件和相应的输入组件,比如 InputTextInputSelect 等等。

EditForm 组件将渲染一个标准的 HTML form 元素,因此您可以使用 method 属性来指定表单是否应该发送 POST 请求。 GET 请求不支持 EditForm 事件处理程序。

提交表单时,请求将被路由到相应的页面,然后由具有 handler 处理程序查询字符串参数指定的匹配表单处理程序名称的表单处理。可以使用 FormHandlerName 属性 为 EditForm 指定表单处理程序名称。如果页面上只有一个表单,则不需要指定名称。然后你可以使用 EditForm 事件处理表单提交。

对模型绑定和验证请求数据的支持尚未实现(即将实现!)但您可以使用FormDataProvider 服务手动处理请求数据。 FormDataProvider.Entries 属性提供对表单数据的访问, FormDataProvider.Name 属性指定所需的表单处理程序。

以下是 Blazor 中一个简单的服务器端渲染表单的样子:

@inject FormDataProvider FormData
<EditForm method="POST" Model="exampleModel" OnValidSubmit="HandleSubmit"><InputText @bind-Value="exampleModel.Name" /><button type="submit">Submit</button>
</EditForm>
@code {ExampleModel exampleModel = new();protected override void OnInitialized(){// Manually model bind the form data using the FormDataProvider serviceif (FormData.Entries.TryGetValue("Name", out var nameValues)){exampleModel.Name = nameValues.First();}}void HandleSubmit(){// Handle the submitted form data}public class ExampleModel{public string? Name { get; set; }}
}

在 Blazor 中路由到命名元素

Blazor 现在支持使用客户端路由,使用标准 URL 片段导航到页面上的特定 HTML 元素。如果使用标准id 属性为 HTML 元素指定标识符,那么当 URL 片段与元素标识符匹配时,Blazor 将正确滚动到该元素。

Webcil 为 Blazor WebAssembly 应用程序打包

您现在可以使用 Blazor WebAssembly 应用程序试用新的 Webcil 软件包。Webcil .NET 程序集的 web 友好包。它会删除任何特定于本机 Windows 执行的内容,以避免在部署到组织下载或使用 .dll 文件的环境时出现问题。

要使 Blazor WebAssembly 应用程序能够使用 Webcil,请将 WasmEnableWebcil 属性添加到项目文件中:

<PropertyGroup><WasmEnableWebcil>true</WasmEnableWebcil>
</PropertyGroup>

如果您在环境中使用 .webcil 文件时遇到问题,请在 GitHub 上创建 issue 让我们知道。

API 编写

minimal API 中表单绑定的扩展支持

此预览版本介绍了对在 minimal API 中绑定到表单类型的扩展支持。现在可以在不需要FromForm 属性的情况下推断基于表单的参数。对基于表单的参数支持包括:IFormCollectionIFormFile 以及 IFormFileCollection。为表单参数推断 OpenAPI 元数据,以支持与 Swagger UI 的集成。

以下代码样例展示了如何实现一个 minimal API,通过利用从IFormFile 类型推断的绑定来处理文件上传。

var app = WebApplication.Create();
string GetOrCreateFilePath(string fileName, string filesDirectory = "uploadFiles")
{var directoryPath = Path.Combine(app.Environment.ContentRootPath, filesDirectory);Directory.CreateDirectory(directoryPath);return Path.Combine(directoryPath, fileName);
}
async Task UploadFileWithName(IFormFile file, string fileSaveName)
{var filePath = GetOrCreateFilePath(fileSaveName);await using var fileStream = new FileStream(filePath, FileMode.Create);await file.CopyToAsync(fileStream);
}
app.MapPost("/upload", async (IFormFile file) => {var fileSaveName = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);await UploadFileWithName(file, fileSaveName);return TypedResults.Ok("File uploaded successfully!");
});
app.Run();

这一功能在使用基于运行时的代码生成以及在利用新的编译时代码生成的本地 AOT 场景的 minimal API 中得到支持。

注意:在应用程序中实现表单时,防御 XSRF 攻击 非常重要。 此 代码样例 概述了如何使用 ASP.NET 中的防伪服务来支持在 minimal API 中生成和验证防伪令牌。

API 项目模板包含 .http 文件

API 项目模板(通过dotnet new api生成)现在包含一个.http 文件,可用于从 Visual Studio 中的新 HTTP 编辑器向应用程序中定义的端点发送请求。

@MyApi_HostAddress = http://localhost:5233
GET {{MyApi_HostAddress}}/todos/
Accept: application/json
###
GET {{MyApi_HostAddress}}/todos/1
Accept: application/json
###

Native AOT

编译时生成的 minimal API 的日志记录和异常处理

运行时生成的最小 API 支持在参数绑定失败时自动记录日志(或在开发环境中抛出异常)。在此预览中,我们引入了对在编译时通过 Request Delegate Generator (RDG)生成的 API 的相同支持。
考虑以下 API 端点,我们通过设置<EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator>启用了 RDG:

var app = WebApplication.Create();
app.MapGet("/hello/{name}", (string name)=> $"Hello {name}!");
app.MapGet("/age", (DateTime birthDate)=> $"You're about {DateTime.Now.Year - birthDate.Year} years old!");
app.Run();

发送以下请求将抛出一个BadHttpRequestException ,因为路由或查询字符串中没有提供所需的name 参数。

curl "http://localhost:5056/hello"
Microsoft.AspNetCore.Http.BadHttpRequestException: Required parameter "string name" was not provided from route or query string.....at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

类似地,向/age 端点发送带有不可解析的birthDate 值将抛出异常。

curl "http://localhost:5056/age?birthDate=invalidDate"
Microsoft.AspNetCore.Http.BadHttpRequestException: Failed to bind parameter "DateTime birthDate" from "invalidDate"....at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

ASP.NET Core 顶级 API 注释以去除警告

为帮助开发人员了解哪些功能与 Native AOT 不兼容,我们注释了不能与 Native AOT 可靠工作的子系统的主要入口点。当从启用了 Native AOT 的应用程序调用这些方法时,开发人员将收到警告。例如,以下代码段将在调用AddControllers 时生成警告,以指示此 API 不安全。
在这里插入图片描述

通过可配置的 HTTPS 支持缩小应用程序大小

在预览版4中,我们进一步减少了不需要 HTTPS 或 HTTP/3 支持的应用程序的 Native AOT 二进制大小。这对于在 TLS 终端代理(例如,托管在 Azure 上)后面运行的应用程序来说非常常见。

当您使用新的 new WebApplication.CreateSlimBuilder时,默认情况下不会包括此功能。它可以通过分别调用builder.WebHost.UseKestrelHttpsConfiguration()builder.WebHost.UseQuic()来重新添加。

由于这些和其他更改,我们可以从预览3更新我们的表:

我们在基准测试实验室中运行了一个简单的 ASP.NET Core API 应用程序,来比较使用和不使用 Native AOT 发布的应用程序大小、内存使用、启动时间和 CPU 负载的差异:

发布种类启动时间(ms)应用程序大小(MB)
Default16988.5
Native AOT – Preview 33411.3
Native AOT – Preview 4329.3

请注意应用程序大小这 2 MB 的减小。

您可以在我们的公共基准仪表盘上探索这些以及更多指标。

Worker Service 模板更新

ASP.NET Core 中的 Worker Service 模板(可通过dotnet new worker获得)现在包括对--aot 标志的支持以启用 AOT 发布来创建 Worker Service 项目。

dotnet new worker -o WorkerWithAot --aot

模板也进行了更新,以利用简化的HostApplicationBuilder 来配置应用程序主机。

using WorkerWithAot;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();
var host = builder.Build();
host.Run();

在 slim builder 中配置的其他默认服务

.NET 8 Preview 3 中引入的 WebApplication.CreateSlimBuilder API,初始化应用程序中的基本功能,以最小化其部署大小。在 .NET 8 Preview 4 中,我们更新了SlimBuilder 使其包含以下功能,以改善开发体验,同时仍将应用程序的总体大小保持在10 MB 以下。

  • appsettings.json 和 appsettings 的 JSON 文件配置
    {EnvironmentName}.json
  • 用户机密配置
  • 控制台日志记录
  • 日志记录配置

API 模板 JSON 配置更改

我们在 .NET 8 Preview 3 中引入了新的 API 项目模板。在 Preview 4 中,使用 --aot 选项使用此模板创建的项目,已更改为将应用程序的源代码生成的 JsonSerializationContext 插入到 JsonSerializerOptions.TypeInfoResolverChain的开头。以前生成的代码使用了JsonSerializerOptions.AddContext<T> API,并且使用 Preview 3 版本的模板创建的任何项目都应更新为调用新的 API。

您可在 .NET 8 Preview 4发布 中阅读有关JsonSerializerOptions.TypeInfoResolverChain API 的更多信息。

支持编译器生成的 IAsyncEnumerable 无法表达类型的 JSON 序列化

现在支持由 C# 编译器实现的IAsyncEnumerable<T> 实现的 JSON 序列化,从而在配置为发布 native AOT 的 ASP.NET Core 项目中开房了它们的使用。如果路由处理程序返回调用 API 的结果,该 API 使用IAsyncEnumerable<T>yield return 异步返回枚举的结果,例如从数据库查询中具体化行(示例),那么这将非常有用。

您可以在 .NET 8 Preview 4发布中了解更多关于 JSON 序列化程序对无法表达类型的支持。

认证和授权

标识 API 端点

我们很高兴介绍MapIdentityApi<TUser>() ,它是一种扩展方法,添加了两个新的 API 端点(/register/login )。MapIdentityApi 的主要目标是使开发人员能够轻松地在基于 JavaScript 的单页应用程序(SPA)或 Blazor 应用程序中使用 ASP.NET Core Identity 进行身份验证。MapIdentityApi 没有使用基于 Razor Pages 的 ASP.NET Core Identity 提供的默认 UI,而是添加了更适合 SPA 应用程序和非浏览器应用程序的 JSON API 端点。

除了用户注册和登录之外,身份 API 端点还将在即将到来的预览中支持双重身份验证和电子邮件验证等功能。您可以在 ASP.NET Core GitHub 存储库上标记为 feature-token-identity 的 issue 中找到计划功能的列表。

以下展示了 ASP.NET Core 应用程序的Program.cs ,该应用程序使用 MapIdentityApi 来启用 opaque bearer token 和 cookie 身份验证。要单独启用 cookie 或令牌身份验证,您可以直接调用现有的AddCookie 或新的AddBearerToken AuthenticationBuilder 扩展方法。两者都是通过下面的AddIdentityApiEndpoints 方法完成的:

// usings ... 
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlite(builder.Configuration["ConnectionString"]));
builder.Services.AddIdentityApiEndpoints<IdentityUser>().AddEntityFrameworkStores<ApplicationDbContext>();
var app = builder.Build();
app.MapGroup("/identity").MapIdentityApi<IdentityUser>();
app.MapGet("/requires-auth", (ClaimsPrincipal user) => $"Hello, {user.Identity?.Name}!").RequireAuthorization();
app.Run();
// public class ApplicationDbContext : IdentityDbContext<IdentityUser> ...

在客户端上,假设httpClientusernamepassword 已在 .NET 控制台应用程序中初始化,则可以如下调用 /register 端点:

// Email confirmation will be added later.
// The request body is: { "username": "<username>", "password": "<password>" }
await httpClient.PostAsJsonAsync("/identity/register", new { username, password });

您可以使用 /login 端点登录并获得 opaque bearer token:

// 2fa flow will be added later.
// The request body is: { "username": "<username>", "password": "<password>" }
var loginResponse = await httpClient.PostAsJsonAsync("/identity/login", new { username, password });
// loginResponse is similar to the "Access Token Response" defined in the OAuth 2 spec
// {
//   "token_type": "Bearer",
//   "access_token": "...",
//   "expires_in": 3600
// }
// refresh token is likely to be added later
var loginContent = await loginResponse.Content.ReadFromJsonAsync<JsonElement>();
var accessToken = loginContent.GetProperty("access_token").GetString();
httpClient.DefaultRequestHeaders.Authorization = new("Bearer", accessToken);
Console.WriteLine(await httpClient.GetStringAsync("/requires-auth"));

或者,如果您想获得一个 cookie,您可以在 /login 队列字符串中设置 ?cookieMode=true

// HttpClientHandler.UseCookies is true by default on supported platforms.
// The request body is: { "username": "<username>", "password": "<password>" }
await httpClient.PostAsJsonAsync("/identity/login?cookieMode=true", new { username, password });
Console.WriteLine(await httpClient.GetStringAsync("/requires-auth"));

我们期待您对我们早期工作的反馈,以改善 SPA 和移动应用程序的身份体验。

改进使用 IAuthorizationRequirementData的自定义认证策略的支持

在此预览版本之前,向端点添加参数化授权策略需要编写大量代码。

  • 为每个策略实现 AuthorizeAttribute
  • 实现 AuthorizationPolicyProvider 以处理基于字符串的合同中的自定义策略
  • 为策略实现 AuthorizationRequirement
  • 为每个需求实现一个 AuthorizationHandler

下面是自定义参数化策略的部分实现。未删节版本包含完整的代码。

var builder = WebApplication.CreateBuilder();
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
builder.Services.AddSingleton<IAuthorizationPolicyProvider, MinimumAgePolicyProvider>();
builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeAuthorizationHandler>();
var app = builder.Build();
app.MapControllers();
app.Run();
[ApiController]
[Route("api/[controller]")]
public class GreetingsController : Controller
{[MinimumAgeAuthorize(16)][HttpGet("hello")]public string Hello(ClaimsPrincipal user) => $"Hello {(user.Identity?.Name ?? "world")}!";
}
class MinimumAgeAuthorizeAttribute : AuthorizeAttribute { }
class MinimumAgePolicyProvider : IAuthorizationPolicyProvider { }
class MinimumAgeRequirement : IAuthorizationRequirement { }
class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeRequirement> { }

此预览引入了IAuthorizationRequirementData 接口,该接口允许属性定义也指定与授权策略相关联的要求。通过利用这一变化,我们可以用更少的代码行重新实现我们的自定义授权策略。未删节版本包含完整的代码。

var builder = WebApplication.CreateBuilder();
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeAuthorizationHandler>();
var app = builder.Build();
app.MapControllers();
app.Run();
[ApiController]
[Route("api/[controller]")]
public class GreetingsController : Controller
{[MinimumAgeAuthorize(16)][HttpGet("hello")]public string Hello(ClaimsPrincipal user) => $"Hello {(user.Identity?.Name ?? "world")}!";
}
class MinimumAgeAuthorizeAttribute : AuthorizeAttribute, IAuthorizationRequirement, IAuthorizationRequirementData
{public MinimumAgeAuthorizeAttribute(int age) => Age =age;public int Age { get; }public IEnumerable<IAuthorizationRequirement> GetRequirements(){yield return this;}
}
class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeAuthorizeAttribute>
{protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeAuthorizeAttribute requirement) { ... }
}

ASP.NET Core metrics

Metrics 是随着时间的推移报告的测量结果,最常用于监控应用程序的运行状况和生成警报。例如报告失败 HTTP 请求的计数器可以显示在仪表盘中,或者在失败超过阈值时生成警报。

此预览版本使用 System.Diagnostics.Metrics 在整个 ASP.NET Core 中添加了新的指标。Metrics 是一个现代 API,用于报告和收集有关应用程序的信息。

与现有事件计数器相比,Metrics 提供了许多改进:

  • 具有计数器、仪表和直方图的新型测量
  • 具有多维价值的强大报告
  • 通过与 Open Telemetry 标准保持一致,集成到更广泛的云原生生态系统中

Metrics 已经为 ASP.NET Core 托管、Kestrel 和 SignalR 添加了度量。预计未来会有更多的 .NET API 来获取 metrics。

如果您有兴趣尝试 metrics,我们已将 Grafana 仪表盘组合在一起,用于报告 Prometheus 收集的 ASP.NET Core metrics。您可以在 aspnetcore-grafana repository 获取仪表盘,并将其导入到您自己的 Grafana 环境中。
在这里插入图片描述

提供反馈

我们希望您喜欢 .NET 8 中的 ASP.NET Core 预览版。请在 GitHub 上提交 issue 让我们知道您对这些新改进的看法。

感谢您试用 ASP.NET Core!


http://www.ppmy.cn/news/667531.html

相关文章

Buildroot 取消默认QT桌面-迅为RK3588开发板

本小节将讲解如何取消掉默认的 qt 桌面。 首先对开发板进行上电&#xff0c;开发板正常启动后&#xff0c;使用命令“cd /etc/init.d”进入到/etc/init.d 目录 下&#xff0c;然后使用以下命令对开机自启动脚本 rcS 进行查看&#xff0c;如下图所示&#xff1a; vi rcS 从上…

哪些因素会导致咽炎?

无论是急性咽炎还是慢性咽炎&#xff0c;都会让患者十分的难受&#xff0c;尤其在吃饭和说话的时候&#xff0c;嗓子会非常疼&#xff0c;当我们患上慢性咽炎之后&#xff0c;我们一定要及时治疗&#xff0c;要想预防这种疾病&#xff0c;首先要了解这种疾病的发病原因&#xf…

肝内胆管结石带来的五大危害

肝内胆管结石的病因比较复杂&#xff0c;它与患者的饮食习惯、肝内感染以及胆汁淤滞等有密切关系。 肝内胆管结石会带来很大的伤害&#xff0c;具体表现在以下五个方面&#xff1a; 1、会形成胆汁性梗硬变与门脉高压症&#xff0c;弥漫性肝内胆管结石可逐步导致胆汁性肝硬化&am…

初中物理60个重要知识点

1、匀速直线运动的速度一定不变&#xff0c;速度一定是一个定值&#xff0c;与路程不成正比&#xff0c;时间不成反比。 2、平均速度不是速度的平均值&#xff0c;只能是总路程除以这段路程上花费的所有时间&#xff0c;包含中间停的时间。 3、密度不是一定不变的。密度是物质…

笔记-动物病理(2:水肿)

动物病理 水肿 edema 水肿 edema 概念 过多的水液在组织间隙或体腔中蓄积(等渗性液体在细胞间隙积聚过多)称水肿。发生于体腔的称积水(hydrops)&#xff0c;积水是水肿的特殊形式。 原因 发生机理 血管通透性升高 #mermaid-svg-gCsfhQz3sWi2zz8m .label{font-family:trebuc…

神经网络 - 痒的生理原理

瘙痒是皮肤浅层游离神经末梢或无髓神经网受到物理、化学剌激后产生兴奋&#xff0c;传到大脑产生痒感。痒感和痛觉在皮肤上都呈点状分布&#xff0c;密度相似。人体痒感受各部位并不一致&#xff0c;脚底、腋窝、肛门、会阴、耳道、眼脸、鼻孔等处最敏感。一般伤口愈合时&#…

oracle 跨裤访问,oracle数据裤表,怎么才能过滤掉我不想要的数据啊?

【单选题】营养学专家建议我国青少年要多吃奶、蛋、鱼,肉等含蛋白质丰富的食品,因为蛋白质是 A. 身体生长发育必需的物质 B. 主要供能物质 C. 容易消化的物质 D. 有机物 【简答题】练习经济业务对会计等式的影响: 偿还一笔债务。 资产、负债、所有者权益发生何种变化?会计恒等…

每天6道题之第十三题:字符串解码(栈)

前言 题目描述 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b;输入字符串中没有额外的空格&…

慢性咽炎治疗方法

慢性咽炎 慢性咽炎的常见因素包括以下六类&#xff1a; (1)病原微生物&#xff1a;包括细菌、病毒、螺旋体、立克次体等&#xff0c;是急性咽炎的主要致病因素&#xff0c;可直接来源于空气、饮食&#xff0c;也可间接来源于血液循环和淋巴循环。 (2)物理或化学性刺激&#…

数显之家快讯:【SHIO世硕心语】2021年,中国最赚钱的时代到来!

数显之家快讯&#xff1a;【SHIO世硕心语】2021年&#xff0c;中国最赚钱的时代到来&#xff01;&#xff08;必读&#xff09;     站在2020年的尾巴上遥望&#xff0c;2021年必将是中国经济的新起点.   一切旧模式都将尘归尘&#xff0c;土归土&#xff0c;各种新模式和…

江西赣州计算机应用中心,赣州计算机应用与维修专业学校

35.回声测距要注意除以2。 36.光线要注意加箭头&#xff0c;要注意实线与虚线的差异。实像的光线是实线。法线、虚像光线的延伸线是虚线。 37.反射和折射总是一起发生的&#xff0c;南昌中专学校排名江西计算机中专学校排名&#xff0c;漫反射和镜面反射都恪守光的反射定律。由…

华为和“字节”,终于干起来了!

来源&#xff1a;字母榜&#xff08;ID&#xff1a;wujicaijing&#xff09; 作者&#xff1a;赵晋杰 一出科技巨头版的《哥斯拉大战金刚》即将上演&#xff1a;华为和字节跳动这两家之前从未有过交集的巨无霸&#xff0c;在时代的驱赶和自身发展的驱动下&#xff0c;在线下卖车…

【渝粤教育】国家开放大学2019年春季 2114人体解剖生理学 参考试题

试卷代号&#xff1a;2114 人体解剖生理学 试题 2019年7月 一、单项选择题&#xff08;每题2分&#xff0c;共80分&#xff09; 1.上皮组织的特点不包括&#xff08; &#xff09;。 A.包括被覆上皮和腺上皮 B.分布于体表及有腔器官的腔面 C.含丰富血管、神经 D.具有保护作用 E…

如何学习舌诊?

主病及相关研究&#xff1a;正常舌象&#xff1a;舌体柔软&#xff0c;活动自如&#xff0c;颜色淡红&#xff0c;舌面铺有薄薄的、颗粒均匀、干湿适中的白苔&#xff0c;常描写为“淡红舌、薄白苔”。 观舌&#xff0c;主要是观察舌质和舌苔两个方面的变化。舌质&#xff0c;又…

病理与病理生理学【3】

1.由于基因变异而产生APC抵抗的凝血因子是&#xff08;&#xff09; A.FⅡ B.FⅢ C.FⅣ D.FⅤ E.FⅦ 2.全身性shwartzman反应促进DIC发生的原因是&#xff08;&#xff09; A.抗凝物质合成障碍 B.血液高凝状态 C.单核-吞噬细胞系统功能受损 D.微循环障碍 E.纤溶系统受抑制 …

细菌感染和抗生素使用

谷禾健康 人的身体拥有数千种细菌&#xff0c;这些细菌在维持健康方面发挥着重要作用。当这些细菌失控繁殖并侵入身体的其他部位或将有害细菌引入身体的系统时&#xff0c;可能会发生细菌感染。 细菌感染的严重程度取决于所涉及的细菌类型和所感染的部位等。细菌最常感染肠道、…

华为和字节,终于被时代驱赶到了同一条赛道上

本文转载自钛媒体 图片来源视觉中国 文 | 字母榜&#xff0c;作者 | 赵晋杰&#xff0c;编辑 | 彦飞 一出科技巨头版的《哥斯拉大战金刚》即将上演&#xff1a; 华为和字节跳动这两家之前从未有过交集的巨无霸&#xff0c;在时代的驱赶和自身发展的驱动下&#xff0c;在线下卖…

2022电大国家开放大学网上形考任务-人体解剖生理学(本)非免费(非答案)

人体解剖生理学&#xff08;本&#xff09;形考任务1答案 题目&#xff1a;参与膝关节构成的是&#xff08; &#xff09;。: 腓骨上端; 胫骨粗隆; 股骨上端; 腓骨头; 胫骨上端 题目&#xff1a;参与小腿三头肌组成的是&#xff08; &#xff09;。: 比目鱼肌; 腓骨长肌; 胫骨…

基本知识 100032

基本知识 100032 单选题 A1 1.胃癌的癌前病变是指 答案&#xff1a;( E ) A:慢性胃炎 B:胃息肉 C:胃溃疡 D:残胃 E:肠化和异型增生 单选题 A1 2.急性糜烂性出血性胃炎的胃镜检查强调在出血后 答案&#xff1a;( B ) A:12&#xff5e;24h B:24&#xff5e;48h C:4…

笔记-动物病理(炎症)

心肌炎 Notion&#xff1a;心肌炎是指心肌的炎症&#xff0c;一般呈急性经过。根据性质分类 实质性心肌炎间质性心肌炎化脓性心肌炎 实质性心肌炎 以心肌变质性变化为主的炎症&#xff0c;同时伴有较轻微的间质渗出和增生。常见于一些病毒性疾病&#xff0c;如犊牛口蹄疫、…