【Azure Developer】使用Azure PubSub服务示例代码时候遇见了.NET 6.0的代码转换问题

简介: 【Azure Developer】使用Azure PubSub服务示例代码时候遇见了.NET 6.0的代码转换问题

问题描述

当本地环境中安装.NET 6.0后,用指令 dotnet new web 或  dotnet new console 生成的项目,使用的都是新模板生成的Program.cs文件。里面去掉了namespace, class 以及main函数的定义。使得代码更简洁。

生成的 Program.cs 代码为:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();

与示例代码中所使用的代码结构差距十分巨大(示例链接:https://docs.microsoft.com/en-us/azure/azure-web-pubsub/tutorial-subprotocol?tabs=csharp):

using Azure.Messaging.WebPubSub;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace logstream
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAzureClients(builder =>
            {
                builder.AddWebPubSubServiceClient(Configuration["Azure:WebPubSub:ConnectionString"], "stream");
            });
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseStaticFiles();
            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/negotiate", async context =>
                {
                    var service = context.RequestServices.GetRequiredService<WebPubSubServiceClient>();
                    var response = new
                    {
                        url = service.GetClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" }).AbsoluteUri
                    };
                    await context.Response.WriteAsJsonAsync(response);
                });
            });
        }
    }
}

那么如何来定义 ConfigureServices, 如何来 Configure 中的代码呢?如何来解决 CS8803 : Top-level statements must precede namespace and type declarations

问题分析

这是代码由.NET 5.0 到 .NET 6.0的升级转换问题。

在.NET 6 之前,每一个应用程序都将应用的初始化代码拆分放在 Program.cs 和 Startup.cs 文件中。他们是两个独立的类,而在.NET 6.0中,为了简洁,为了最小化API,把两个类进行了合并。生成新的Program.cs中去掉了命名空间(Namespace, Class定义, Main函数)。使得在启动一个应用时,代码达到最少。 (PS:C# 编译器会自动生成Mian函数)

 

在查看官方对于5.0 变为 6.0的文档介绍:https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60?view=aspnetcore-6.0&tabs=visual-studio

  1. ConfigureServices 函数里面的 services.AddXXXXX()等都可以转换为  builder.Services.AddXXXXX()
  2. Configure 函数中的内容,可以直接写在 var app = builder.Build(); 代码之后。

所以,本文之前的代码,可以直接转换为:

using Azure.Messaging.WebPubSub;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var ConnectionString = "";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAzureClients(builder =>
{
    builder.AddWebPubSubServiceClient(ConnectionString, "stream");
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/negotiate", async context =>
    {
        var service = context.RequestServices.GetRequiredService<WebPubSubServiceClient>();
        var response = new
        {
            url = service.GetClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" }).AbsoluteUri
        };
        await context.Response.WriteAsJsonAsync(response);
    });
});
app.MapGet("/", () => "Hello World!");
app.Run();

 

特别注意,在新模板下的代码,非常容易出现:CS8803 : Top-level statements must precede namespace and type declarations 错误。这是因为 .NET 6.0在隐藏了Main函数后,在编译代码时候,会自动补上Main函数,所以在Program.cs 的代码中,如果需要定义其他类,必须放在文件的末尾,不能在文件开头部分和中间。

当Class定义代码放在Program.cs开头部分

当Class定义代码放在Program.cs中间部分

当Class定义代码放在Program.cs结尾部分

更多关于Top-level statements的说明,请见:https://www.cnblogs.com/lulight/articles/16285885.html

 

参考资料

Tutorial: Publish and subscribe messages between WebSocket clients using subprotocol: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/tutorial-subprotocol?tabs=csharp

 

Migrate from ASP.NET Core 5.0 to 6.0:https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60?view=aspnetcore-6.0&tabs=visual-studio

 

C# 9.0 - Introduction To Top-Level Statements :https://www.c-sharpcorner.com/article/c-sharp-9-0-top-level-statement/#:~:text=Top%20Level%20statements%20should%20be%20first%20before%20any,Top-level%20Statements.%20That%E2%80%99s%20all%20for%20the%20Top-level%20statement. 

当在复杂的环境中面临问题,格物之道需:浊而静之徐

相关文章
|
2月前
|
Kubernetes 监控 Devops
【独家揭秘】.NET项目中的DevOps实践:从代码提交到生产部署,你不知道的那些事!
【8月更文挑战第28天】.NET 项目中的 DevOps 实践贯穿代码提交到生产部署全流程,涵盖健壮的源代码管理、GitFlow 工作流、持续集成与部署、容器化及监控日志记录。通过 Git、CI/CD 工具、Kubernetes 及日志框架的最佳实践应用,显著提升软件开发效率与质量。本文通过具体示例,助力开发者构建高效可靠的 DevOps 流程,确保项目成功交付。
48 0
|
2月前
|
XML 开发框架 .NET
.NET框架:软件开发领域的瑞士军刀,如何让初学者变身代码艺术家——从基础架构到独特优势,一篇不可错过的深度解读。
【8月更文挑战第28天】.NET框架是由微软推出的统一开发平台,支持多种编程语言,简化应用程序的开发与部署。其核心组件包括公共语言运行库(CLR)和类库(FCL)。CLR负责内存管理、线程管理和异常处理等任务,确保代码稳定运行;FCL则提供了丰富的类和接口,涵盖网络、数据访问、安全性等多个领域,提高开发效率。此外,.NET框架还支持跨语言互操作,允许开发者使用C#、VB.NET等语言编写代码并无缝集成。这一框架凭借其强大的功能和广泛的社区支持,已成为软件开发领域的重要工具,适合初学者深入学习以奠定职业生涯基础。
90 1
|
2月前
|
存储 NoSQL Redis
【Azure Developer】一个复制Redis Key到另一个Redis服务的工具(redis_copy_net8)
【Azure Developer】一个复制Redis Key到另一个Redis服务的工具(redis_copy_net8)
【Azure Developer】一个复制Redis Key到另一个Redis服务的工具(redis_copy_net8)
|
2月前
|
监控 Cloud Native 开发者
云端精英的.NET微服务秘籍:Azure上的创新实战演练
【8月更文挑战第28天】在现代软件开发中,微服务架构通过分解应用程序提升可维护性和扩展性。结合Azure与.NET框架,开发者能轻松打造高效且易管理的云原生微服务。首先,使用Docker容器化.NET应用,并借助Azure Kubernetes Service(AKS)或Azure Container Instances(ACI)部署。为确保高可用性和伸缩性,可利用Azure Traffic Manager负载均衡及Azure Autoscale动态调整实例数。
23 0
|
2月前
|
开发框架 .NET C#
【Azure Developer】C# / .NET 静态函数中this关键字的作用
【Azure Developer】C# / .NET 静态函数中this关键字的作用
|
2月前
|
存储 Linux 网络安全
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Linux/Linux Container)
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Linux/Linux Container)
|
2月前
|
开发框架 前端开发 JavaScript
【Azure App Service】.NET应用读取静态文件时遇见了404错误的解决方法
【Azure App Service】.NET应用读取静态文件时遇见了404错误的解决方法
|
2月前
|
网络安全 API 数据安全/隐私保护
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
|
2月前
|
C# C++
【Azure Function】在VS Code中创建Function项目遇见 No .NET worker runtimes found
【Azure Function】在VS Code中创建Function项目遇见 No .NET worker runtimes found
|
26天前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
27 7
下一篇
无影云桌面