You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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的WebApp profile中applicationUrl为http://localhost:8080,与Program.cs绑定端口一致
  • 确认Swagger中间件顺序:UseSwagger()和UseSwaggerUI()需放在UseRouting()之后、UseEndpoints()之前

5. 请求Body格式修正

  • 控制器方法接收[FromBody] string roomData,但Postman发送的是JSON对象,模型绑定会失败。可修改参数为对应实体类(如RoomMetadata),或调整输入格式化器解析逻辑

内容的提问来源于stack exchange,提问作者kannan srank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 23:17:01