using EdiApiGateway.Models; using EdiApiGateway.Services; using Microsoft.AspNetCore.Diagnostics; var builder = WebApplication.CreateBuilder(args); // Shift_JISエンコーディング対応(詳細ログ付き) Console.WriteLine("========== Encoding Provider Registration =========="); try { Console.WriteLine($"Before: Available encodings = {System.Text.Encoding.GetEncodings().Length}"); System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); Console.WriteLine("✅ Encoding provider registered successfully"); Console.WriteLine($"After: Available encodings = {System.Text.Encoding.GetEncodings().Length}"); // Shift-JIS が利用可能か確認 var shiftJis = System.Text.Encoding.GetEncoding("Shift_JIS"); Console.WriteLine($"✅ Shift-JIS encoding available: {shiftJis.EncodingName} (CodePage: {shiftJis.CodePage})"); // テスト文字列のエンコード・デコード string testString = "COM073: TCP-Z手順エラー"; byte[] encoded = shiftJis.GetBytes(testString); string decoded = shiftJis.GetString(encoded); Console.WriteLine($"✅ Encoding test: '{testString}' -> {encoded.Length} bytes -> '{decoded}'"); if (testString == decoded) { Console.WriteLine("✅ Encoding/Decoding test PASSED"); } else { Console.WriteLine($"❌ Encoding/Decoding test FAILED: Expected '{testString}', Got '{decoded}'"); } } catch (Exception ex) { Console.WriteLine($"❌ Failed to register encoding provider: {ex.GetType().Name}: {ex.Message}"); Console.WriteLine($"Stack trace: {ex.StackTrace}"); } Console.WriteLine("===================================================="); // サービス登録(Phase 2C: 明示的なDI設定) builder.Services.AddSingleton(serviceProvider => { var configuration = serviceProvider.GetRequiredService(); var logger = serviceProvider.GetRequiredService>(); return new EdiCommunicationService(configuration, logger); }); // JSON シリアライゼーション設定(Phase 1B) builder.Services.ConfigureHttpJsonOptions(options => { // Defaultエンコーダーを使用して制御文字を適切にエスケープ // UnsafeRelaxedJsonEscapingはCSVデータ内の制御文字で問題を起こす可能性があるため変更 options.SerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Default; // プロパティ名をそのまま使用(PascalCase維持) options.SerializerOptions.PropertyNamingPolicy = null; }); var app = builder.Build(); // グローバル例外ハンドラー(Phase 1A + Priority 1詳細化) app.UseExceptionHandler(exceptionHandlerApp => { exceptionHandlerApp.Run(async context => { context.Response.StatusCode = StatusCodes.Status500InternalServerError; context.Response.ContentType = "application/json"; var exceptionHandlerPathFeature = context.Features.Get(); var error = exceptionHandlerPathFeature?.Error; var errorMessage = error?.Message ?? "An unexpected error occurred"; var logger = context.RequestServices.GetRequiredService>(); // 詳細なコンテキスト情報をログ記録(Priority 1追加) logger.LogError(error, "[Exception Handler] Unhandled exception occurred: Path={Path}, Method={Method}, ErrorType={ErrorType}, ErrorMessage={ErrorMessage}", context.Request.Path.ToString(), context.Request.Method, error?.GetType().Name ?? "Unknown", errorMessage); // スタックトレースを別途詳細ログで記録 if (error?.StackTrace != null) { logger.LogDebug("[Exception Handler] StackTrace: {StackTrace}", error.StackTrace); } await context.Response.WriteAsJsonAsync(new { success = false, error = errorMessage, type = error?.GetType().Name, timestamp = DateTime.Now }); logger.LogInformation("[Exception Handler] Error response sent: StatusCode=500, ContentType=application/json"); }); }); // ヘルスチェック app.MapGet("/", (ILogger logger) => { logger.LogInformation("[API /] Health check request received"); var response = new { service = "EDI API Gateway", version = "1.0.0", mode = "Client Mode (Call Mode)", dll = "ACMSCTL1.DLL" }; logger.LogInformation("[API /] Health check response: {@Response}", response); return response; }); // POST /api/edi/receive - EDIデータ受信 app.MapPost("/api/edi/receive", (ReceiveRequest request, EdiCommunicationService service, ILogger logger) => { // リクエスト受信ログ(Priority 1追加) logger.LogInformation("[API /api/edi/receive] Request received: Partner={Partner}, Cycle={Cycle}, Denbun={Denbun}, SaveFileName={SaveFileName}", request.Partner ?? "(null)", request.Cycle, request.Denbun, request.SaveFileName ?? "(null)"); if (string.IsNullOrEmpty(request.Partner)) { logger.LogWarning("[API /api/edi/receive] BadRequest: Partner is required"); return Results.BadRequest(new { error = "Partner is required" }); } var response = service.ReceiveFile(request); // レスポンス送信直前ログ(Priority 1追加) var statusCode = response.Success ? 200 : 400; logger.LogInformation("[API /api/edi/receive] Sending response: StatusCode={StatusCode}, Success={Success}, ReturnCode={ReturnCode}, FileContent={ContentLen}, FileContentRaw={RawLen}, Error={Error}", statusCode, response.Success, response.ReturnCode, response.FileContent?.Length ?? 0, response.FileContentRaw?.Length ?? 0, response.Error ?? "(none)"); // JSONシリアライズデバッグログ追加(制御文字の適切なエスケープ確認) try { // 実際のHTTP JSON設定を使用してシリアライズテスト var jsonOptions = new System.Text.Json.JsonSerializerOptions { Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Default, PropertyNamingPolicy = null }; var testJson = System.Text.Json.JsonSerializer.Serialize(response, jsonOptions); logger.LogInformation("[API /api/edi/receive] ✅ JSON serialization test successful with Default encoder: {Length} bytes", testJson.Length); } catch (Exception jsonEx) { logger.LogError(jsonEx, "[API /api/edi/receive] ❌ JSON serialization FAILED"); logger.LogError("[API /api/edi/receive] Error details: Type={ErrorType}, Message={ErrorMessage}", jsonEx.GetType().Name, jsonEx.Message); return Results.Problem(detail: $"JSON serialization error: {jsonEx.Message}", statusCode: 500); } return response.Success ? Results.Ok(response) : Results.BadRequest(response); }); // POST /api/edi/send - EDIデータ送信 app.MapPost("/api/edi/send", (SendRequest request, EdiCommunicationService service, ILogger logger) => { // リクエスト受信ログ(Priority 1追加) logger.LogInformation("[API /api/edi/send] Request received: Partner={Partner}, FilePath={FilePath}", request.Partner ?? "(null)", request.FilePath ?? "(null)"); if (string.IsNullOrEmpty(request.Partner)) { logger.LogWarning("[API /api/edi/send] BadRequest: Partner is required"); return Results.BadRequest(new { error = "Partner is required" }); } var response = service.SendFile(request); // レスポンス送信直前ログ(Priority 1追加) var statusCode = response.Success ? 200 : 400; logger.LogInformation("[API /api/edi/send] Sending response: StatusCode={StatusCode}, Success={Success}, ReturnCode={ReturnCode}, Error={Error}", statusCode, response.Success, response.ReturnCode, response.Error ?? "(none)"); return response.Success ? Results.Ok(response) : Results.BadRequest(response); }); app.Run();