VSCode开发ASP.NET Core全栈指南:MVC与API双模实战
1. 项目概述为什么在VSCode里跑ASP.NET Core不是“凑合用”而是真能干活的正经方案很多人第一次听说“用VSCode写ASP.NET Core”时第一反应是“啊不装Visual Studio也能干这个”——这背后其实藏着一个被长期低估的事实VSCode .NET SDK 的组合早已不是玩具级替代品而是生产环境里高频、稳定、可复现的主力开发栈。我从2018年第一个.NET Core 2.1项目开始就在纯VSCode环境下交付过电商后台API、工业数据采集Web服务、政府内网审批系统MVC应用累计上线项目超17个其中12个至今仍在零故障运行。它不依赖Windows、不绑定庞大IDE、不强制安装Gigabyte级工具链但能完整支撑从Controller路由定义、Model验证、EF Core迁移、Razor视图渲染到Swagger文档自动生成、JWT鉴权、Docker容器打包的全链路开发闭环。核心关键词——VSCode、C#、ASP.NET Core、WEB MVC、API——不是孤立标签而是一套可落地的技术契约VSCode提供轻量可定制的编辑器底座C#作为强类型、高生产力语言承担业务逻辑表达ASP.NET Core是跨平台、高性能、模块化设计的Web框架内核WEB MVC负责传统页面驱动型交互比如后台管理页、报表展示页API则专注前后端分离场景下的JSON数据契约交付如React/Vue前端调用、IoT设备上报接口。这五者叠加解决的是真实世界里最普遍的两类需求需要用户直接操作的Web界面系统MVC和需要被其他程序调用的数据服务系统API。适合谁参考三类人特别受益一是高校学生刚学C#不想被Visual Studio安装包和许可证卡住入门节奏二是嵌入式/工控领域工程师常需在Linux或WSL下快速搭一个轻量Web配置页VSCodedotnet CLI就是最短路径三是中小团队后端开发者既要维护老MVC后台又要输出新API接口一套环境双轨并行切换成本几乎为零。我试过让实习生用VSCode三天内完成一个带登录、权限控制、Excel导出的仓储管理系统MVC版全程没碰过Visual Studio——关键不是“能不能”而是“怎么让每一步都稳、快、可追溯”。2. 整体设计思路与方案选型逻辑为什么放弃Visual Studio选择VSCode这条“硬核但高效”的路2.1 不是“退而求其次”而是主动做减法VSCode CLI 的底层逻辑Visual Studio确实功能强大但它本质是一个“全功能操作系统级IDE”内置设计器、调试器、性能分析器、测试管理器、UI构建器……这些对大型企业级应用是刚需但对快速验证原型、搭建内部工具、教学演示、CI/CD流水线集成来说反而成了负担。VSCode走的是另一条路——它不提供功能只提供扩展能力不预设流程只暴露接口。你装的不是“ASP.NET开发套件”而是几个精准插件C#由OmniSharp驱动、.NET Install Tool、C# Extensions、REST Client。它们像乐高积木一样只拼你需要的那一块。举个实际例子我要给工厂PLC写一个HTTP状态上报接口。用Visual Studio新建项目要等30秒加载模板、生成一堆.csproj配置、打开设计器窗格……而VSCode里敲一行命令dotnet new webapi -n PlcStatusApi0.8秒生成完整项目骨架code .打开即写连解决方案文件.sln都不需要。这不是偷懒而是把时间花在真正该花的地方——比如调试Modbus TCP通信时序而不是等IDE加载NuGet包索引。2.2 为什么必须用.NET 6版本选择背后的兼容性真相标题里没写版本但实操中这是生死线。ASP.NET Core 5已停止支持.NET 7进入维护期当前唯一推荐的基线是.NET 6 LTS支持到2024年11月或.NET 8 LTS支持到2026年11月。原因很实在.NET 5及更早版本的dotnet new mvc模板默认启用Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation这在Linux/WSL下极易因文件监控机制差异导致热重载失败.NET 6起引入Minimal Hosting Model精简宿主模型Startup.cs彻底消失Program.cs变成单文件入口配置代码行数减少40%且天然适配VSCode的轻量调试.NET 8新增Native AOT编译支持一个dotnet publish -r linux-x64 --self-contained -p:PublishTrimmedtrue就能打出5MB大小的独立可执行文件这对边缘计算场景如树莓派部署Web API是降维打击。我踩过的坑曾用.NET 5在WSL2里跑MVC结果model指令在Razor视图里总报“无法解析类型”查了两天才发现是Razor SDK版本与.NET 5 Runtime不匹配——换.NET 6后dotnet restore自动拉取正确SDK问题消失。版本不是玄学是微软官方明确标注的兼容矩阵。2.3 MVC与API项目结构的本质差异不是“多选一”而是“按需组合”新手常误以为MVC和API是互斥模板。实际上ASP.NET Core项目类型是逻辑分层不是物理隔离。一个项目完全可以同时承载MVC视图和API控制器——只要在Program.cs里注册对应服务即可var builder WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); // 启用MVC builder.Services.AddEndpointsApiExplorer(); // 启用API元数据Swagger需要 builder.Services.AddSwaggerGen(); // 启用Swagger UI区别在于默认模板的“开箱即用”侧重dotnet new mvc自带Controllers/HomeController.cs、Views/Home/Index.cshtml、wwwroot/静态资源目录强调HTML渲染dotnet new webapi自带Controllers/WeatherForecastController.cs、无视图目录、默认返回JSON强调REST契约但你可以随时在webapi项目里加AddControllersWithViews()然后创建.cshtml文件也可以在mvc项目里删掉AddControllersWithViews()只留AddControllers()让它变成纯API服务。我做过一个混合项目前台用Razor Pages做管理员配置页MVC逻辑后台用[ApiController]提供WebSocket消息推送接口API逻辑共用同一套Entity Framework Core DbContext共享JWT认证中间件——这才是真实业务里的常态。3. 核心细节解析与实操要点从零配置VSCode到跑通第一个Hello World3.1 环境准备三步到位拒绝“教程里能跑我电脑上不行”很多教程失败根源在环境链断裂。以下步骤经我反复验证Windows 10/11、Ubuntu 22.04、WSL2 Ubuntu 22.04、macOS Sonoma均通过第一步安装.NET SDK非Runtime访问 .NET下载页 务必选择“.NET SDK”而非“.NET Runtime”Windows选x64 installerLinux用apt-getUbuntu/Debian或yumCentOS/RHELmacOS用brew install --cask dotnet-sdk验证终端执行dotnet --version输出应为8.0.100或6.0.400LTS版本提示如果显示command not foundLinux/macOS需将~/.dotnet/tools加入PATHWindows需重启终端或重新登录。第二步VSCode插件安装仅4个必要项插件名作者必要性关键作用C#Microsoft★★★★★提供IntelliSense、跳转、重构底层是OmniSharp服务器.NET Install Toolms-dotnettools★★★★☆一键安装/切换不同.NET SDK版本避免手动下载C# Extensionsjchannon★★★☆☆补充代码片段如propfull生成完整属性、快速生成构造函数REST Clienthumao★★★☆☆直接在.http文件里发HTTP请求比Postman更贴合开发流注意禁用所有“C# Dev Kit”、“C# Extension Pack”等捆绑包——它们会强制安装冗余组件且与OmniSharp冲突。我见过三次因“Dev Kit”导致VSCode调试时断点失效卸载后立刻恢复。第三步VSCode设置微调解决90%新手困惑在VSCode设置Ctrl,中搜索并修改C# OmniSharp: Use Modern Net→true启用.NET 6新协议Files: Auto Save→afterDelay避免频繁保存触发多余编译Editor: Format On Save→trueC#格式化依赖dotnet-format首次保存会自动安装C# OmniSharp: Dotnet Path→ 留空让插件自动探测手动指定易出错。3.2 创建项目命令行才是VSCode的“真·图形界面”VSCode里点“文件→新建项目”那是假动作。真实流程永远始于终端创建MVC项目带Razor视图dotnet new mvc -n MyMvcApp --framework net8.0 cd MyMvcApp code .创建API项目纯JSON接口dotnet new webapi -n MyApiService --framework net8.0 cd MyApiService code .关键参数说明-n MyMvcApp项目名同时生成解决方案文件夹名--framework net8.0必须显式指定否则默认用最新SDK可能是preview版导致dotnet run报错生成的.csproj文件里会看到TargetFrameworknet8.0/TargetFramework这是编译目标不是运行时版本。实操心得不要用dotnet new mvc --help查参数——它列出30多个选项90%用不到。记住三个高频参数就够了-n名字、--framework框架、-o输出路径如-o ./src。我习惯把项目建在~/dev/下避免中文路径和空格曾因路径含C:\我的项目\导致dotnet restore卡死20分钟。3.3 Program.cs深度解析从“魔法代码”到可掌控的入口.NET 6的Program.cs是理解整个应用生命周期的钥匙。以MVC项目为例var builder WebApplication.CreateBuilder(args); // 1. 创建Builder配置容器、日志、配置源 builder.Services.AddControllersWithViews(); // 2. 注册MVC服务含Razor视图引擎、模型绑定 var app builder.Build(); // 3. 构建应用中间件管道、路由、静态文件 if (!app.Environment.IsDevelopment()) // 4. 开发环境特有中间件 { app.UseExceptionHandler(/Error); // 错误处理页 app.UseHsts(); // HTTPS强制跳转 } app.UseHttpsRedirection(); // 5. 生产就绪中间件HTTPS重定向 app.UseStaticFiles(); // 静态文件服务css/js/img app.UseRouting(); // 路由中间件必须在UseEndpoints前 app.UseAuthorization(); // 授权中间件需配合AddAuthorization app.MapControllerRoute( // 6. MVC路由映射 name: default, pattern: {controllerHome}/{actionIndex}/{id?}); app.Run(); // 7. 启动监听逐行拆解价值点第1行WebApplication.CreateBuilder(args)不是简单new对象而是自动加载appsettings.json、环境变量、命令行参数比.NET 5的WebHostBuilder更智能第2行AddControllersWithViews()内部调用AddRazorViewEngine()、AddDataAnnotations()、AddJsonOptions()一次性注入MVC所需全部服务无需手动AddSingleton第4-5行环境判断app.Environment.IsDevelopment()读取DOTNET_ENVIRONMENT环境变量默认值Development发布时设为Production即可关闭开发中间件第6行MapControllerRoute{controllerHome}表示默认控制器是HomeController{actionIndex}表示默认Action是Index{id?}表示id是可选参数——这就是URL/自动映射到Home/Index的原理。注意API项目Program.cs更精简没有AddControllersWithViews()而是AddControllers()且路由映射用app.MapControllers()——它基于[Route]和[HttpGet]等特性自动发现控制器不用手写路由模板。4. 实操过程与核心环节实现手把手跑通MVC页面与API接口4.1 MVC项目实战从空白页面到带数据的仪表盘Step 1启动并验证基础页面在VSCode终端执行dotnet run输出类似info: Microsoft.Hosting.Lifetime[14] Now listening on: https://localhost:7265 Now listening on: http://localhost:5265浏览器访问https://localhost:7265忽略证书警告看到默认首页——这证明Kestrel服务器、路由、Razor引擎全部就绪。Step 2创建新控制器与视图以“产品管理”为例在Controllers/下新建ProductsController.csusing Microsoft.AspNetCore.Mvc; namespace MyMvcApp.Controllers; public class ProductsController : Controller { public IActionResult Index() View(); // 返回Views/Products/Index.cshtml }在Views/下新建文件夹Products再建Index.cshtml{ ViewData[Title] 产品列表; } h1ViewData[Title]/h1 p这里是产品管理页面。/p重启应用或启用热重载dotnet watch run访问https://localhost:7265/Products页面正常显示。Step 3接入真实数据EF Core SQLite轻量方案安装NuGet包终端执行dotnet add package Microsoft.EntityFrameworkCore.Sqlite创建Model在Models/下建Product.csnamespace MyMvcApp.Models; public class Product { public int Id { get; set; } public string Name { get; set; } string.Empty; public decimal Price { get; set; } }创建DbContext在Data/下建AppDbContext.csusing Microsoft.EntityFrameworkCore; using MyMvcApp.Models; namespace MyMvcApp.Data; public class AppDbContext : DbContext { public AppDbContext(DbContextOptionsAppDbContext options) : base(options) { } public DbSetProduct Products { get; set; } }注册DbContext在Program.cs的builder.Services区域添加builder.Services.AddDbContextAppDbContext(options options.UseSqlite(builder.Configuration.GetConnectionString(DefaultConnection)));配置连接字符串在appsettings.json的ConnectionStrings节添加ConnectionStrings: { DefaultConnection: Data Sourceapp.db }生成迁移并更新数据库终端执行dotnet ef migrations add InitialCreate dotnet ef database update提示首次执行dotnet ef需先安装全局工具dotnet tool install --global dotnet-ef。SQLite文件app.db会自动生成在项目根目录。Step 4在视图中显示数据修改Views/Products/Index.cshtmlmodel IEnumerableMyMvcApp.Models.Product { ViewData[Title] 产品列表; } h1ViewData[Title]/h1 table classtable thead trthID/thth名称/thth价格/th/tr /thead tbody foreach (var p in Model) { trtdp.Id/tdtdp.Name/tdtdp.Price/td/tr } /tbody /table修改ProductsController.cs的Index方法private readonly AppDbContext _context; public ProductsController(AppDbContext context) _context context; public async TaskIActionResult Index() View(await _context.Products.ToListAsync());重启应用页面显示数据库中的产品数据——MVC数据流闭环完成。4.2 API项目实战从Hello World到带JWT认证的REST服务Step 1创建并测试基础APIdotnet new webapi -n MyApiService --framework net8.0后Controllers/WeatherForecastController.cs已存在。运行dotnet run访问https://localhost:5001/weatherforecast返回JSON数组——这是API项目的“Hello World”。Step 2定义领域模型与DTO避免直接暴露Entity在Models/下建User.cs实体namespace MyApiService.Models; public class User { public int Id { get; set; } public string Username { get; set; } string.Empty; public string PasswordHash { get; set; } string.Empty; // 实际应加密存储 }在Dto/下建LoginRequest.cs输入DTOnamespace MyApiService.Dto; public class LoginRequest { public string Username { get; set; } string.Empty; public string Password { get; set; } string.Empty; }在Dto/下建TokenResponse.cs输出DTOnamespace MyApiService.Dto; public class TokenResponse { public string Token { get; set; } string.Empty; public DateTime Expires { get; set; } }Step 3实现JWT认证精简版生产环境需加强安装包dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer在Program.cs中添加认证服务// 添加认证服务放在AddControllers前 builder.Services.AddAuthentication(Bearer) .AddJwtBearer(Bearer, options { options.TokenValidationParameters new TokenValidationParameters { ValidateIssuerSigningKey true, IssuerSigningKey new SymmetricSecurityKey(Encoding.UTF8.GetBytes(your-32-byte-secret-key-here)), ValidateIssuer false, ValidateAudience false }; }); // 启用认证中间件放在UseRouting后UseEndpoints前 app.UseAuthentication(); app.UseAuthorization();创建AuthController.csusing Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using MyApiService.Dto; using MyApiService.Models; namespace MyApiService.Controllers; [ApiController] [Route(api/[controller])] public class AuthController : ControllerBase { [HttpPost(login)] public ActionResultTokenResponse Login([FromBody] LoginRequest request) { // 模拟用户验证实际应查数据库 if (request.Username admin request.Password 123456) { var token GenerateJwtToken(request.Username); return Ok(new TokenResponse { Token token, Expires DateTime.UtcNow.AddHours(1) }); } return Unauthorized(); } private string GenerateJwtToken(string username) { var key Encoding.UTF8.GetBytes(your-32-byte-secret-key-here); var tokenDescriptor new SecurityTokenDescriptor { Subject new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, username) }), Expires DateTime.UtcNow.AddHours(1), SigningCredentials new SigningCredentials( new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var tokenHandler new JwtSecurityTokenHandler(); var securityToken tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(securityToken); } }测试用VSCode的REST Client插件新建test.http文件POST https://localhost:5001/api/auth/login Content-Type: application/json { username: admin, password: 123456 }发送后返回JWT Token——认证环节打通。Step 4保护API端点在需要认证的Controller上加[Authorize][ApiController] [Route(api/[controller])] [Authorize] // ← 这一行让所有Action都需要Token public class ProductsController : ControllerBase { [HttpGet] public ActionResultIEnumerablestring Get() Ok(new[] { Product1, Product2 }); }再次访问https://localhost:5001/api/products返回401 Unauthorized带上TokenGET https://localhost:5001/api/products Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...返回正常数据——API安全闭环完成。5. 常见问题与排查技巧实录那些官网不写的“踩坑现场”5.1 VSCode调试断点不命中90%是这3个原因现象根本原因解决方案断点灰显未激活OmniSharp未启动或版本不匹配查看VSCode右下角状态栏点击.NET图标选择“Restart OmniSharp Server”若提示“Failed to start OmniSharp”检查.NET SDK是否安装且dotnet --list-sdks有输出断点命中但不暂停项目未启用调试符号pdb文件在.csproj中确认有DebugTypeportable/DebugType.NET 6默认开启删除bin/和obj/文件夹后dotnet build重建断点在Controller里命中但在Model里不命中类库项目未正确引用若Model在单独类库中确保.csproj有ProjectReference Include..\MyModels\MyModels.csproj /且类库目标框架与主项目一致如都是net8.0实操心得我遇到过一次断点失效最终发现是WSL2里/home/user/路径含中文用户名OmniSharp生成的pdb路径乱码。解决方案在WSL2里用useradd -m -s /bin/bash eng新建英文用户名彻底规避路径问题。5.2dotnet run报错“Unable to start Kestrel”网络端口是隐形杀手错误日志常含System.IO.IOException: Failed to bind to address https://[::]:5001。这不是代码问题而是端口被占Windowsnetstat -ano | findstr :5001找PIDtaskkill /PID PID /F杀进程Linux/WSLsudo lsof -i :5001或sudo ss -tulpn | grep :5001sudo kill -9 PIDmacOSlsof -i :5001kill -9 PID但更根本的解法是改用随机端口在Program.cs中修改var builder WebApplication.CreateBuilder(new WebApplicationOptions { Args args, ApplicationName typeof(Program).Assembly.FullName, ContentRootPath Directory.GetCurrentDirectory(), WebRootPath wwwroot, // 关键让Kestrel自动分配空闲端口 WebRootFileProvider null }); builder.WebHost.ConfigureKestrel(serverOptions { serverOptions.ListenAnyIP(0); // 0表示随机端口 });然后运行dotnet run终端会输出实际端口如Now listening on: https://localhost:54321——这招在CI/CD流水线里尤其有用避免端口冲突。5.3 Razor视图编译失败model指令报错的真相常见错误The type or namespace name MyModel could not be found。表面是命名空间问题实则是Razor编译上下文缺失原因1视图文件未设为Content在.csproj中检查ItemGroup Content UpdateViews\**\*.cshtml CopyToOutputDirectoryPreserveNewest/CopyToOutputDirectory /Content /ItemGroup缺少此段会导致.cshtml不参与编译model无法解析类型。原因2模型类在类库中未引用到Web项目若MyModel在MyModels.dll中确保Web项目.csproj有ItemGroup ProjectReference Include..\MyModels\MyModels.csproj / /ItemGroup原因3Razor SDK版本与.NET SDK不匹配手动在.csproj中强制指定PropertyGroup RazorSdkVersion8.0.0/RazorSdkVersion /PropertyGroup注意不要用using MyModels硬编码命名空间——Razor视图默认继承_ViewImports.cshtml里的using指令。在Views/下建_ViewImports.cshtml内容为using MyMvcApp.Models addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers这样所有视图自动可用model Product。5.4 API返回400 Bad RequestSchema校验的隐藏规则热搜词里高频出现api error: 400 invalid schema for function artifact这通常发生在调用第三方API如DeepSeek时但ASP.NET Core自身也有类似陷阱DTO属性缺少[Required]但前端传nullLoginRequest中Username若为string类型前端传{username:null,password:123}模型绑定失败返回400。解决方案启用[Required]特性public string Username { get; set; } string.Empty;[Required]或在Program.cs中全局配置builder.Services.ConfigureApiBehaviorOptions(options { options.SuppressModelStateInvalidFilter true; // 关闭默认400响应 });JSON日期格式不兼容前端传2023-10-01C#DateTime默认要求ISO格式2023-10-01T00:00:00。解决方案在Program.cs中统一配置builder.Services.ConfigureJsonOptions(options { options.SerializerOptions.PropertyNamingPolicy JsonNamingPolicy.CamelCase; options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); // 允许宽松日期解析 options.SerializerOptions.ParseOptions new JsonDocumentOptions { AllowTrailingCommas true, CommentHandling JsonCommentHandling.Skip }; });5.5 性能瓶颈自查清单当dotnet run变慢先看这5项检查项命令/方法正常值异常表现SDK版本碎片化dotnet --list-sdks≤3个版本列出10个旧版本dotnet restore会遍历所有版本缓存NuGet源缓慢dotnet nuget list source仅https://api.nuget.org/v3/index.json存在私有源超时dotnet restore卡住OmniSharp日志爆炸VSCode输出面板→选择“OmniSharp Log”每秒≤5行INFO每秒百行WARNINGCPU飙升WSL2磁盘IO瓶颈WSL2终端执行iostat -x 1%util 30%%util 90%dotnet build耗时翻倍VSCode插件冲突禁用所有插件仅留C#dotnet run启动3秒启动15秒内存占用2GB我的终极提速方案在WSL2里用/mnt/d/NTFS挂载盘存代码立刻禁用改用/home/user/dev/ext4原生文件系统dotnet build速度提升3倍。NTFS在WSL2下文件操作延迟高达200ms而ext4仅2ms——这点在dotnet watch run热重载时感知最明显。6. 工程化延伸从单机开发到生产部署的平滑过渡6.1 Docker容器化三行命令打包ASP.NET Core应用VSCode里写完代码下一步不是“发给运维”而是自己打包成容器镜像Step 1添加Dockerfile放在项目根目录FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY . . RUN dotnet restore ./MyMvcApp.csproj RUN dotnet build ./MyMvcApp.csproj -c Release -o /app/build FROM build AS publish RUN dotnet publish ./MyMvcApp.csproj -c Release -o /app/publish /p:UseAppHostfalse FROM base AS final WORKDIR /app COPY --frompublish /app/publish . ENTRYPOINT [dotnet, MyMvcApp.dll]Step 2构建并运行docker build -t my-mvc-app . docker run -d -p 8080:80 --name mvc-container my-mvc-app浏览器访问http://localhost:8080——和dotnet run效果完全一致但这是跨平台、可复现的生产镜像。提示.dockerignore文件必不可少内容为**/.git **/.vscode **/bin **/obj **/.env避免把VSCode配置和编译产物打进镜像镜像体积从500MB直降到180MB。6.2 GitHub Actions自动化Push代码即部署在项目根目录建.github/workflows/ci.ymlname: Build and Deploy on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Setup .NET uses: actions/setup-dotnetv3 with: dotnet-version: 8.x - name: Restore dependencies run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - name: Test run: dotnet test --no-restore --verbosity normal - name: Publish run: dotnet publish -c Release -o ./publish - name: Deploy to Server uses: appleboy/scp-actionv0.1.6 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} password: ${{ secrets.PASSWORD }} source: publish/** target: /var/www/myapp/配置Secrets后每次git pushGitHub自动完成构建、测试、发布——VSCode开发、Git管理、CI/CD交付形成完整DevOps闭环。6.3 日志与监控用Serilog替代Console.WriteLineConsole.WriteLine在生产环境毫无价值。替换为Serilog安装包dotnet add package Serilog.AspNetCore在Program.cs中using Serilog; Log.Logger new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console() .WriteTo.File(logs/myapp-.txt, rollingInterval: RollingInterval.Day) .CreateBootstrapLogger(); var builder WebApplication.CreateBuilder(args); builder.Host.UseSerilog(); // ← 关键替换默认日志提供程序启动后所有ILoggerT注入的日志自动写入logs/目录按天滚动支持结构化JSON输出——这才是可观测性的起点。我在一个物联网项目里用SerilogSeq开源日志服务器实时监控100设备API调用当某台设备连续5次返回401自动触发告警邮件——这种能力是Console.WriteLine永远做不到的。7. 最后一点个人体会VSCode不是“简化版Visual Studio”而是“开发者主权宣言”写这篇长文时我翻出了2019年在树莓派4上用VSCodedotnet CLI部署的第一个Web API截图终端里dotnet run
上一篇/下一篇内容由系统自动关联
返回资讯列表 →