.NET Core Web API本地调试:断点未触发+Postman网关超时求助
.NET Core 6 Web API本地运行调试问题
- 克隆项目后本地运行,Postman请求
http://localhost:8080/saveRoom返回Gateway Timeout,断点完全无法触发 - 已关闭Postman代理和SSL设置,公司代理环境下仍无法命中代码
- 开发环境下Swagger无法打开,修改默认端口为8080并添加Serilog后出现该问题
- 尝试带/不带Bearer Token均无效果,开发环境预期无需认证
相关代码
Program.cs
public class Program { static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration .ReadFrom.Configuration(hostingContext.Configuration) .Enrich.FromLogContext() .WriteTo.Console() .WriteTo.Fluentd("fluentd.rx-system.svc.cluster.local", 24284, "myappAppService")) .ConfigureWebHostDefaults(webBuilder => { webBuilder .UseStartup<Startup>() .UseUrls("http://*:8080") .ConfigureKestrel(serverOptions => serverOptions.ConfigureHttpsDefaults(options => options.OnAuthenticate = (_, authenticationOptions) => authenticationOptions.CipherSuitesPolicy = new CipherSuitesPolicy( new[] { TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TlsCipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 }))); }); }
launchsettings.json
{ "$schema": "http://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:36959", "sslPort": 44392 } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "WebApp": { "commandName": "Project", "dotnetRunMessages": "true", "launchBrowser": true, "launchUrl": "swagger", "applicationUrl": "https://localhost:5001;http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
Startup.cs
using System; using System.Threading.Tasks; using AspNetCoreRateLimit; using IdentityModel.AspNetCore.OAuth2Introspection; using webapp.Controllers; using webapp.DataModel; using webapp.Repository; using webapp.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace webapp { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } private IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { var openIdConfiguration = Configuration.GetSection("OpenID"); var baseUrl = openIdConfiguration.GetSection("BaseURL").Value; var clientId = openIdConfiguration.GetSection("ClientID").Value; var clientSecret = openIdConfiguration.GetSection("ClientSecret").Value; var serviceProvider = services.BuildServiceProvider(); var logger = serviceProvider.GetService<ILogger<Startup>>(); services.AddDistributedMemoryCache(); services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme) .AddOAuth2Introspection(options => { options.EnableCaching = true; options.CacheDuration = new TimeSpan(0, 1, 0, 0); options.Authority = baseUrl; options.ClientId = clientId; options.ClientSecret = clientSecret; options.Events.OnAuthenticationFailed = ctxt => { logger.LogInformation($"Authentication failure for {ctxt?.Principal?.Identity?.Name}"); return Task.CompletedTask; }; }); services.AddOptions(); services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); services.AddSingleton<IIpPolicyStore, DistributedCacheIpPolicyStore>(); services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>(); services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); services.AddDistributedRateLimiting<AsyncKeyLockProcessingStrategy>(); services.AddControllers(); services.AddSingleton(Configuration); services.AddDbContext<RoomDbContext>(optionsBuilder => optionsBuilder.UseNpgsql(Configuration.GetConnectionString("RoomDb"), options => options.EnableRetryOnFailure())); services.AddSingleton<IAuthenticationService>(provider => new AuthenticationService(baseUrl, provider.GetRequiredService<ILogger<AuthenticationService>>())); services.AddScoped<IS3Repository, S3Repository>(provider => new S3Repository( provider.GetRequiredService<ILogger<S3Repository>>(), Configuration)); services.AddScoped<IRoomDataService, RoomDataService>(provider => new RoomDataService( provider.GetRequiredService<ILogger<RoomDataService>>(), provider.GetRequiredService<RoomDbContext>(), provider.GetRequiredService<IS3Repository>())); services.AddScoped<ApiExceptionFilter>(); services.AddMvc(options => { options.InputFormatters.Insert(0, new RawJsonBodyInputFormatter()); }); services.AddSwaggerGen(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { using var scope = app.ApplicationServices.CreateScope(); var services = scope.ServiceProvider; var dbContext = services.GetRequiredService<RoomDbContext>(); dbContext.Database.EnsureCreated(); try { var databaseCreator = dbContext.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator; databaseCreator.CreateTables(); } catch (Exception ex) { Console.WriteLine("Error while creation database tables (maybe they exist already?)"); } app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseIpRateLimiting(); app.Use(async (context, next) => { context.Response.Headers.Add("X-Content-Type-Options", "nosniff"); context.Response.Headers.Add("Strict-Transport-Security", "max-age=31536000; includeSubdomains"); await next(); }); if (env.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseEndpoints(endpoints => { if (env.IsDevelopment()) { // endpoints.MapControllers().WithMetadata(new AllowAnonymousAttribute()); } else { endpoints.MapControllers(); } }); } } }
控制器代码
using System.Collections.Generic; using System.Threading.Tasks; using System.Web; using webapp.DataModel; using webapp.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Schema; namespace webapp.Controllers { [Authorize] [ApiController] [Route("/")] [ServiceFilter(typeof(ApiExceptionFilter))] public class RoomDataController : ControllerBase { private const string ROOM_SCHEMA_LOCATION = "Schemas/room.schema.json"; private readonly ILogger<RoomDataController> _log; private readonly IRoomDataService _roomDataService; private readonly JSchema _roomSchema; public RoomDataController(ILogger<RoomDataController> log, IRoomDataService roomDataService) { _log = log; _roomDataService = roomDataService; _roomSchema = JSchema.Parse(System.IO.File.ReadAllText(ROOM_SCHEMA_LOCATION)); } [HttpPost("saveRoom")] public async Task<ActionResult<RoomMetadata>> SaveRoom([FromBody] string roomData) { Request.Headers.TryGetValue("Entitlement", out var entitlement); roomData = HttpUtility.UrlDecode(roomData); if (string.IsNullOrWhiteSpace(entitlement) || string.IsNullOrWhiteSpace(roomData)) { _log.LogWarning($"POST /saveRoom without entitlement"); return BadRequest(); } _log.LogInformation($"POST /saveRoom entitlement={entitlement}"); var roomObject = JObject.Parse(roomData); if (!roomObject.IsValid(_roomSchema)) { return BadRequest(); } return await _roomDataService.SaveRoom(entitlement, roomData); } } }
Postman请求信息
- 请求地址:
http://localhost:8080/saveRoom - 请求头:添加
Entitlement字段 - 请求Body:
{ "Id": "example_id", "Entitlement": "example_entitlement", "Filename": "example_filename", "Timestamp": "2023-06-27T12:00:00" }
解决思路
1. 端口与服务启动验证
- 检查8080端口占用:执行
netstat -ano | findstr ":8080",若被占用则更换端口或终止占用进程 - 确认服务监听端口:启动项目后查看控制台输出,验证Kestrel是否绑定到
http://*:8080 - 直接访问
http://localhost:8080,确认是否有基础响应(如404),排除网关层面阻塞
2. 认证环节阻塞修复
- 开发环境取消注释
endpoints.MapControllers().WithMetadata(new AllowAnonymousAttribute()),控制器加了[Authorize],未认证请求会被拦截导致超时 - 若本地无有效OpenID服务,暂时注释Startup.cs中认证相关代码,验证请求是否能命中控制器
3. Serilog Fluentd连接问题
- Program.cs中配置的
fluentd.rx-system.svc.cluster.local是集群内部地址,本地无法访问,会导致服务启动阻塞。暂时注释.WriteTo.Fluentd(...)部分,验证服务是否正常响应
4. Swagger访问修复
- 同步launchsettings.json的
WebAppprofile中applicationUrl为http://localhost:8080,与Program.cs绑定端口一致 - 确认Swagger中间件顺序:
UseSwagger()和UseSwaggerUI()需放在UseRouting()之后、UseEndpoints()之前
5. 请求Body格式修正
- 控制器方法接收
[FromBody] string roomData,但Postman发送的是JSON对象,模型绑定会失败。可修改参数为对应实体类(如RoomMetadata),或调整输入格式化器解析逻辑
内容的提问来源于stack exchange,提问作者kannan srank
相关产品推荐
相关产品推荐

