问题描述

当本地环境中安装.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

 
 

Migrate from ASP.NET Core 5.0 to 6.0

 

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

  1. 【Azure Developer】解决Azure Key Vault管理Storage的示例代码在中国区Azure遇见的各种认证/授权问题 - C# Example Code

    问题描述 使用Azure密钥保管库(Key Vault)来托管存储账号(Storage Account)密钥的示例中,从Github中下载的示例代码在中国区Azure运行时候会遇见各种认证和授权问题, ...

  2. 【Azure Developer】Azure Logic App 示例: 解析 Request Body 的 JSON 的表达式? triggerBody()?

    问题描述 通过Azure Logic App(逻辑应用)实现无代码的处理JSON数据.但是如何获取Request Body中的一个属性值呢? 例如:如何来获取以下JSON结构中的 ObjectName ...

  3. 【Azure Developer】Azure Automation 自动化账号生成的时候怎么生成连接 与证书 (Connection & Certificate)

    Azure Automation :The Azure Automation service provides a highly reliable and scalable workflow exec ...

  4. 【Azure Developer】Azure Graph SDK获取用户列表的问题: SDK中GraphServiceClient如何指向中国区的Endpoint:https://microsoftgraph.chinacloudapi.cn/v1.0

    问题描述 想通过Java SDK的方式来获取Azure 门户中所列举的用户.一直报错无法正常调用接口,错误信息与AAD登录认证相关,提示tenant not found. 想要实现的目的,通过代码方式 ...

  5. 【Azure Redis 缓存 Azure Cache For Redis】Redis性能问题,发现Server Load非常的高,导致正常连接/操作不成功

    问题描述 在正常使用Azure Redis的服务中,突然发现Redis 的CPU达到了100%, 正常的使用中发现性能问题严重.从Redis的门户图表中,观察到CPU, Connection,Lent ...

  6. 【Azure Developer】App Service + PubSub +JS 实现多人版黑客帝国文字流效果图

    需要描述 1)实现黑客帝国文字流效果图,JS功能 2)部署在云中,让大家都可以访问,App Service实现 3)大家都能发送消息,并显示在文字流中,PubSub(websocket)实现 终极效果 ...

  7. 【Azure Developer】Python代码通过AAD认证访问微软Azure密钥保管库(Azure Key Vault)中机密信息(Secret)

    关键字说明 什么是 Azure Active Directory?Azure Active Directory(Azure AD, AAD) 是 Microsoft 的基于云的标识和访问管理服务,可帮 ...

  8. 【Azure 存储服务】代码版 Azure Storage Blob 生成 SAS (Shared Access Signature: 共享访问签名)

    问题描述 在使用Azure存储服务,为了有效的保护Storage的Access Keys.可以使用另一种授权方式访问资源(Shared Access Signature: 共享访问签名), 它的好处可 ...

  9. 【Azure 环境】【Azure Developer】使用Python代码获取Azure 中的资源的Metrics定义及数据

    问题描述 使用Python SDK来获取Azure上的各种资源的Metrics的名称以及Metrics Data的示例 问题解答 通过 azure-monitor-query ,可以创建一个 metr ...

随机推荐

  1. C# 委托专题

    单播委托:一个委托只指向一个方法: 多播委托:一个委托指向多个方法,形成一个方法链: Main是静态方法,里面只能引用静态方法,而不能引用实例方法: Main可以进行类的实例化,然后引用实例化后的方法 ...

  2. 手机上无法显示Toast信息

    关于手机上无法显示Toast信息, 是因为手机上的权限没有开, 在应用管理处将所有权限都打开,就可以显示了.

  3. 多态,动态方法调度(dynamic method dispatch)?

    8.多态Polymorphism,向上转型Upcasting,动态方法调度(dynamic method dispatch) 什么叫多态?简言之,马 克 - t o - w i n:就是父类引用指向子 ...

  4. Blazor组件自做四 : 使用JS隔离封装signature_pad签名组件

    运行截图 演示地址 响应式演示 感谢szimek写的棒棒的signature_pad.js项目, 来源: https://github.com/szimek/signature_pad 正式开始 1. ...

  5. HDMS(Headend Device Management System)软件下载

    进入官网http://www.pbi-china.com/CHS/index.aspx点击右下角的下载通道.

  6. python循环与基本数据类型内置方法

    今天又是充满希望的一天呢 一.python循环 1.wuile与else连用 当while没有被关键'break'主动结束的情况下 正常结束循环体代码之后会执行else的子代码 "" ...

  7. vim 下几种比较省劲的方式(vi结合着用)

    Vim的几种模式 正常模式:可以使用快捷键命令,或按:输入命令行. 插入模式:可以输入文本,在正常模式下,按i.a.o等都可以进入插入模式. 可视模式:正常模式下按v可以进入可视模式, 在可视模式下, ...

  8. redis 指定db库导入导出数据

    最近根据之前的项目重新改编一个新的项目,发现上一个项目的搭建者,把一些区域权限和划分放在redis上存储,因此不得不照搬过来,所以搜索一下相关如何做的 发现一个比较简单的做法,记录一下操作过程,方便以 ...

  9. sqlplus文件查看自带oracle命令的执行过程

    问题描述:看到一篇文章 在$ORACLE_HOME/bin/sqlplus中可以查看到数据库命令的查询语句.可以直接编辑sqlplus文件,查到到我们平时标准系统命令的原脚本,但是自己进行编辑查看却是 ...

  10. GopherCon SG 2019 "Understanding Allocations" 学习笔记

    本篇是根据 GopherCon SG 2019 "Understanding Allocations" 演讲的学习笔记. Understanding Allocations: th ...