【解決方法】ブレークポイントにヒットできず、 "通知: ゲートウェイタイムアウト" postman を使用して .NET Core Web API をテストするときにエラーが発生する

プログラミングQA


私は .NET Core Web API 開発の初心者で、最近会社でプロジェクトに取り組み始めました。 GitHub から .NET Core 6.0 Web API プロジェクトを複製し、ローカルで実行しようとしています。 ただし、Postman を使用してテストすると、コード内のブレークポイントがヒットしません。 現在、会社のプロキシの背後で作業していますが、Postman のすべてのプロキシと SSL 設定を無効にしています。 努力にもかかわらず、Postman からリクエストを送信するときに API をコードにヒットさせることができませんでした。

数日間この問題のトラブルシューティングを試みましたが、解決策が見つかりませんでした。 Postman からリクエストを送信するときにコードがヒットしない理由がわかりません。また、何がこのブロックの原因となっているのかもわかりません。

さらに、Postman で API をテストしようとすると、「通知: ゲートウェイ タイムアウト」エラーが表示されます。 これは開発環境なので、ベアラー トークンを渡す必要はないと思います。 トークンを使用した場合と使用しない場合の両方でリクエストを送信してみましたが、何も変わらないようです。

デフォルトのポート (8080) をバイパスし、カスタム ロガーを追加したことは言及しておく価値があります。これにより、開発環境で Swagger が開かないようになっているようです。 ただし、Postman を使用して API をテストすると、この問題が発生します。

この問題を解決するために、ご支援やご指導をいただければ幸いです。 よろしくお願いいたします。

私が試したこと:

ポストマンで実行しています- http://localhost:8080/saveRoom

ヘッダーを資格として渡し、

体のような

{ “ID”: “example_id”、”資格”: “example_entitlement”、”ファイル名”: “example_filename”、”タイムスタンプ”: “2023-06-27T12:00:00” }

私のprogram.csクラス

C#
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
                                       })));
               });
   }

私の起動設定.json

C#
{
  "$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,
      "launc

       hUrl": "swagger",
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

私のスタートアップクラス

C#
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();
                }
            });
        }
    }
}

コントローラーメソッド

C#
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);
        }
    }
}

C#
i am running in post man- http://localhost:8080/saveRoom

passing header as Entitlement and

 body like 


{
  "Id": "example_id",
  "Entitlement": "example_entitlement",
  "Filename": "example_filename",
  "Timestamp": "2023-06-27T12:00:00"
}

コメント

タイトルとURLをコピーしました