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

news2024/11/25 8:19:42

作者: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 service
        if (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.coloradmin.cn/o/702777.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图片:前端展示图像(img 、picture、svg、canvas )及常用图片格式(PNG、JPG、JPEG、WebP、GIF、SVG、AVIF等)

一、浏览器网页展示图片方法 1.1、HTML <img> 标签 <!DOCTYPE html> <html><head><title>图片展示</title></head><body><h1>图片展示</h1><img src"example.jpg" alt"Example Image" w…

项目——学生信息管理系统3

目录 班级添加的界面实现 创建班级的实体类 在org.xingyun.dao 包下 编写 ClassDao 创建 AddStudentClassFrm 添加班级页面 注意创建成 JInternalFrame 类型 给控件起个名字 注释掉main方法 给提交按钮绑定事件 回到 MainFrm.java 给添加班级按钮绑定事件 启动测试 班…

chatgpt赋能python:Python重写父类的方法

Python重写父类的方法 在Python中&#xff0c;继承是一个常见的概念。通过继承&#xff0c;子类可以使用父类中定义的属性和方法。有时候&#xff0c;子类需要改变父类中的行为。这时候&#xff0c;可以通过重写父类的方法来实现这一目的。 什么是重写方法&#xff1f; 当一…

区块链生态发展

文章目录 前言以太坊的到来什么是图灵完备&#xff1f;什么是智能合约&#xff1f; 以太坊的应用去中心化应用 DApp代币发行 公有链&联盟链区块链应用总结 前言 前面的区块链文章有介绍区块链的诞生以及底层运行原理&#xff0c; 本文主要介绍一下区块链应用的发展&#x…

(八)灌溉系统-将nodejs部署到云服务器(未实现,思路供参考)

这里之后我就是升级优化了 如果不想再学习的话&#xff0c;前面的就足够用了 Node后端部署上线详细步骤及踩坑记录&#xff08;使用宝塔面板&#xff09;&#xff1a;参考文章 Xshelll7下载&#xff1a;教程 这里是成功连上了

如何使用 Terraform 和 Git 分支有效管理多环境?

作者&#xff5c;Sumeet Ninawe 翻译&#xff5c;Seal软件 链接&#xff5c;https://spacelift.io/blog/terraform-environments 通常我们使用 Terraform 将我们的基础设施定义为代码&#xff0c;然后用 Terraform CLI 在我们选择的云平台中创建制定的基础设施组件。从表面上看…

C++primer(第五版)第五章(语句)

5.1简单语句 一个语句在末尾加上分号;就变成了表达式语句.表达式语句的作用是执行表达式并丢弃掉求值结果(也可以用赋值运算符将求值结果存起来),不存起来的话,大多数表达式语句是没有什么实际用处的表达式语句,例如: int a10; a5; //这就是没什么用的表达式语句 ; …

《Linux操作系统编程》第四章 屏幕编程器vi : 了解屏幕编辑器vi的概述和基本操作命令

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

基于单片机自动控制的电动模型汽车

摘 要 本文研究了一种基于单片机自动控制的电动模型汽车。主要论述了自动循迹、避障、测距跟随等自动驾驶相关技术在模型车上的应用。 模型汽车以STM32为主控芯片&#xff0c;采用了多种传感器、驱动电机、控制舵机等检测与控制模块&#xff0c;实现了路径循迹行驶和检测避障的…

【python】numpy的array数组与pandas的DataFrame表格互相转换(图文代码超详细)

目录 0.环境 1.array数组和DataFrame表格的简单介绍 2.转换方式详解&#xff08;代码&#xff09; 0&#xff09;前提&#xff1a;【需注意】 1&#xff09;array转化为DataFrame 2&#xff09;DataFrame转化为array 3&#xff09;完整代码 0.环境 windows jupyter note…

英语统考错题集_作文题---网络教育统考工作笔记003

scholar 学者 下面是关于统考中的作文的如何书写,要打个照面,不能到时候蒙了 sincere 真诚的 cover 覆盖 excited 激动的 兴奋的 sincerely 真诚的 absent 缺勤的 citizen 公民 居民 每种题型都接触一下,然后后面有时间继续扩充中.. 152下上

ansible 变量与事实变量

Ansible变量与事实变量&#xff1a; 自定义变量&#xff1a; 变量可以在定义任务前进行定义&#xff0c;也可以从其他文件中调用。 下面我写了一个在任务前定义的变量&#xff0c;并用循环将其打印。 内部变量&#xff1a; 剧本如下&#xff1a; --- - hosts: localhostva…

基于51单片机开发的步进电机远程控制系统

摘 要 电机是日常生活中必不可少的一部分&#xff0c;同时也是一种常用的机电元件。步进电机是一种特殊的电机&#xff0c;相较于其他类型的电机&#xff0c;步进电机的优点更加突出、应用优势更加明显&#xff0c;广泛应用于各个领域。 本设计是基于单片机开发的步进电机远程…

力扣算法刷题Day47|休息日总结:动态规划之背包问题

背包问题 〉题型分类 解题套路 〉动规五部曲 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 解题技巧 〉递推公式 问背包装满后的最大价值&#xff1a;dp[j] max(dp[j], dp[j - weight[i]] value[i]) …

JMeter之简单控制线程组(Thread Group)组件的执行顺序

jmeter的线程类型一共有3种分别是setUp线程组、tearDown线程组和线程组 他们的执行优先级为 setUp线程组 > 线程组(Thread Group) > tearDown线程组 当存在多个线程组(Thread Group)&#xff0c;jmeter默认是同时执行的&#xff0c;也就是说是无序的&#xff0c;此时如果…

蓝桥杯单片机赛点数据包模块文件使用的注意事项

目录 蓝桥杯单片机赛点数据包模块文件使用的注意事项 前言&#xff1a; 正文&#xff1a; DS1302 IIC onewire 2023年赛点资源包数据包下载地址&#xff1a;https://download.csdn.net/download/qq_25218501/87965408?spm1001.2014.3001.5503 蓝桥杯单片机赛点数据包模块…

redis---基础(部署及常用命令)

目录 前言一、关系型数据库与非关系型数据库1. 关系型数据库2. 非关系型数据库3. 关系型数据库和非关系型数据库区别4. 非关系型数据库产生背景小结&#xff1a; 二、Redis简介1. 单进程快速的原因&#xff1a;2.epoll 机制优势&#xff1a; 三、Redis 具有以下几个优点四、red…

全国农信银CTF流量分析(凯撒会分析流量吗)

总的来说这题还是挺简单的。先分析流量过滤http 发现有f?ag提示&#xff0c;然后分析url 解析得到 &#xff1a;[Request URI: http://192.168.0.111/?codeif [ $(head f?ag | cut -c 1) G ] then sleep 1 echo success 发现是时间盲注 然后过滤 http.time > 1 对过滤…

《移动互联网技术》第三章 无线定位技术:掌握位置服务和室内定位的基本概念和工作原理

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

无线路由器解决方案 MR500E工业级4G路由器可实时监控4G信号强度

近年来&#xff0c;随着物联网技术的快速发展&#xff0c;越来越多的制造企业开始加速推进工业互联网的建设和应用。作为工业互联网的重要基础设施之一&#xff0c;工业级4G路由器也不断迭代升级&#xff0c;以满足企业多样化的应用需求。 无线路由器解决方案MR500E工业4G路由…