.NET 7 Preview 3中的ASP.NET Core更新

目录

开始使用

升级现有项目

在最少的API中支持路由处理程序过滤器

改进了最小路由处理程序的单元可测试性

在MVC和API控制器中使用TryParse绑定

新的Results.Stream()重载

在连接上使用多个流时改进了HTTP/2性能

测量启动时间的新ServerReady事件

开发者异常页面深色模式

给予反馈


.NET 7 Preview 3现已推出,其中包括对ASP.NET Core的许多重大改进。

以下是此预览版中新增功能的摘要:

  • 在最少的API中支持路由处理程序过滤器
  • 改进了最小路由处理程序的单元可测试性
  • 在MVC和API控制器中使用TryParse绑定
  • 新的重载Results.Stream()
  • 在连接上使用多个流时改进了HTTP/2性能
  • 测量启动时间的新ServerReady事件
  • 开发者异常页面深色模式

有关为.NET 7计划的ASP.NET Core工作的更多详细信息,请参阅GitHub的.NET 7的完整ASP.NET Core路线图。

开始使用

要开始使用.NET 7 Preview 3中的ASP.NET Core请安装.NET 7 SDK

如果你在Windows上使用Visual Studio,我们建议安装最新的Visual Studio 2022预览版Visual Studio for Mac.NET 7预览版的支持尚不可用,但即将推出。

要安装最新的.NET WebAssembly构建工具,请从提升的命令提示符处运行以下命令:

dotnet workload install wasm-tools

注意:目前不支持使用.NET 7 SDK.NET 7 WebAssembly构建工具构建.NET 6 Blazor项目。这将在未来的.NET 7更新中解决:dotnet/runtime#65211

升级现有项目

要将现有的ASP.NET Core应用从.NET 7 Preview 2升级到.NET 7 Preview 3

  • 将所有Microsoft.AspNetCore.*包引用更新为.7.0.0-preview.3.*
  • 将所有Microsoft.Extensions.*包引用更新为.7.0.0-preview.3.*

另请参阅.NET 7ASP.NET Core中的重大更改的完整列表。

在最少的API中支持路由处理程序过滤器

在此预览版中,我们介绍了对最小应用程序中路由处理程序中的过滤器的支持。过滤器在核心路由处理程序逻辑之前执行,可用于检查和修改处理程序参数或拦截处理程序执行。

过滤器可以使用多种策略注册到处理程序上。例如,您可以使用RouteHandlerFilterDelegateAddFilter扩展方法注册过滤器,如下所示:

string HelloName(string name) => $"Hello, {name}!";

app.MapGet("/hello/{name}", HelloName)
    .AddFilter(async (routeHandlerInvocationContext, next) =>
    {
        var name = (string) routeHandlerInvocationContext.Parameters[0];
        if (name == "Bob")
        {
            return Results.Problem("No Bob's allowed");
        }
        return await next(routeHandlerInvocationContext);
    });

过滤器也可以通过过滤器工厂策略注册,该策略允许访问RouteHandlerContext, RouteHandlerContext允许访问与处理程序关联的MethodInfo和注册在端点上的元数据。

app.MapGet("/hello/{name}", HelloName)
    .AddFilter((routeHandlerContext, next) =>
    {
        var parameters = routeHandlerContext.MethodInfo.GetParameters();
        var hasCorrectSignature = parameters.Length == 1 && parameters[0].ParameterType == typeof(string);
        return async (routeHandlerInvocationContext) =>
        {
            if (hasCorrectSignature)
            {
                var name = (string) routeHandlerInvocationContext.Parameters[0];
                if (name == "Bob")
                {
                    return Results.Problem("No Bob's allowed");
                }
            }
            return await next(routeHandlerInvocationContext);
        };
    });

最后,过滤器可以实现IRouteHandlerFilter接口并从DI中解析或作为实例传递。

app.MapGet("/hello/{name}", HelloName)
    .AddFilter<MyFilter>();

改进了最小路由处理程序的单元可测试性

IResult实现类型现在在命名空间Microsoft.AspNetCore.Http中以后缀HttpResult (OkObjectHttpResult, ProblemHttpResult) 公开可用。使用这些类型,您现在可以在使用命名方法而不是lambda时更轻松地对最小路由处理程序进行单元测试。

[Fact]
public async Task GetTodoReturnsTodoFromDatabase()
{
    var todo = new Todo { Id = 42, Name = "Improve Results testability!" };
    var mockDb = new MockTodoDb(new[] { todo });

    var result = (OkObjectHttpResult)await TodoEndpoints.GetTodo(mockDb, todo.Id);

    //Assert
    Assert.Equal(200, result.StatusCode);

    var foundTodo = Assert.IsAssignableFrom<Models.Todo>(result.Value);
    Assert.Equal(id, foundTodo.Id);
}

[Fact]
public void CreateTodoWithValidationProblems()
{
    //Arrange
    var newTodo = default(Todo);
    var mockDb = new MockTodoDb();

    //Act
    var result = TodoEndpoints.CreateTodo(mockDb, newTodo);

    //Assert        
    var problemResult = Assert.IsAssignableFrom<ProblemHttpResult>(result);
    Assert.NotNull(problemResult.ProblemDetails);
    Assert.Equal(400, problemResult.StatusCode);
}

MVCAPI控制器中使用TryParse绑定

您现在可以使用TryParse具有以下签名之一的方法绑定控制器操作参数值:

public static bool TryParse(string value, T out result);
public static bool TryParse(string value, IFormatProvider provider, T out result);

例如,以下控制器中的Get操作使用参数类型上的TryParse方法绑定来自查询字符串的数据:

public class TryParseController : ControllerBase
{
    // GET /tryparse?data=MyName
    [HttpGet]
    public ActionResult Get([FromQuery]CustomTryParseObject data) => Ok();

    public class CustomTryParseObject
    {
        public string? Name { get; set; }

        public static bool TryParse(string s, out CustomTryParseObject result)
        {
            if (s is null) 
            {
                result = default;
                return false;
            }

            result = new CustomTryParseObject { Name = s };
            return true;
        }
    }
}

新的Results.Stream()重载

我们引入了新的Results.Stream(...)重载来适应需要访问底层HTTP响应流而不进行缓冲的场景。这些重载还改进了API想要将数据流式传输到HTTP响应流的情况,例如从Azure Blob存储。下面的示例演示了使用ImageSharp进行图像处理时的使用Results.Stream()

app.MapGet("/process-image", async (HttpContext http) =>
{
    using var image = await Image.LoadAsync("puppy.jpeg");
    int width = image.Width / 2;
    int height = image.Height / 2;
    image.Mutate(x => x.Resize(width, height));
    http.Response.Headers.CacheControl = $"public,max-age={FromHours(24).TotalSeconds}";
    return Results.Stream(stream => image.SaveAsync(stream, PngFormat.Instance), "image/png");
});

在连接上使用多个流时改进了HTTP/2性能

我们对HTTP/2帧编写代码进行了更改,以在多个流尝试在单个HTTP/2连接上写入数据时提高性能。我们现在将TLS工作分派到线程池,并更快地释放其他流可以获取以写入其数据的写锁。在争用此写锁的情况下,等待时间的减少可以显着提高性能。在单个连接(使用TLS)上具有70个流的gRPC基准测试显示,随着这一变化,每秒请求数(RPS)提高了约15%

测量启动时间的新ServerReady事件

如果您使用EventSource度量/诊断并想要测量ASP.NET Core应用程序的启动时间,您现在可以使用Microsoft.AspNetCore.Hosting源中的新ServerReady事件,该事件代表您的服务器启动并运行的时间点。

开发者异常页面深色模式

ASP.NET Core开发人员异常页面现在支持暗模式:

感谢@poke贡献了这一改进!

给予反馈

我们希望您喜欢.NET 7中的ASP.NET Core预览版。通过在GitHub上提交问题,让我们知道您对这些新改进的看法。

感谢您试用ASP.NET Core

https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-preview-3/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值