using Microsoft.AspNetCore.Http.Features; using RobotNet.SystemUpgrade; var builder = WebApplication.CreateBuilder(args); builder.Services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default); }); builder.WebHost.ConfigureKestrel(o => { o.Limits.MaxRequestBodySize = 2L * 1024 * 1024 * 1024; }); builder.Services.Configure(o => { o.MultipartBodyLengthLimit = 2L * 1024 * 1024 * 1024; }); var app = builder.Build(); var storeDir = Path.Combine(AppContext.BaseDirectory, "store"); Directory.CreateDirectory(storeDir); var apis = app.MapGroup("/api"); var upload = apis.MapPost("/upload", async (HttpRequest request) => { if (!request.HasFormContentType) return Results.BadRequest("Content-Type phải là multipart/form-data."); var form = await request.ReadFormAsync(); var file = form.Files.FirstOrDefault(); if (file is null || file.Length == 0) return Results.BadRequest("Không có file hoặc file rỗng."); var safeName = Path.GetFileName(file.FileName); var savePath = Path.Combine(storeDir, safeName); await using (var fs = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, 64 * 1024, useAsync: true)) await file.CopyToAsync(fs); var nowUtc = DateTime.UtcNow; try { System.IO.File.SetCreationTimeUtc(savePath, nowUtc); System.IO.File.SetLastWriteTimeUtc(savePath, nowUtc); } catch { } var fi = new FileInfo(savePath); var url = $"/api/files/{Uri.EscapeDataString(fi.Name)}"; return Results.Created(url, new UploadFileResponse(fi.Name, fi.Length, url)); }); apis.MapGet("/files", () => { var list = Directory.EnumerateFiles(storeDir) .Select(p => new FileInfo(p)) .OrderByDescending(f => f.CreationTimeUtc) .Select(f => new FileItem( f.Name, f.Length, f.CreationTimeUtc, $"/api/files/{Uri.EscapeDataString(f.Name)}" )) .ToList(); return Results.Ok(list); }); apis.MapGet("/files/{name}", (string name) => { var safeName = Path.GetFileName(name); var path = Path.Combine(storeDir, safeName); if (!System.IO.File.Exists(path)) return Results.NotFound("Không tìm thấy file."); return Results.File(path, "application/octet-stream", fileDownloadName: safeName); }); apis.MapDelete("/files/{name}", (string name) => { var safeName = Path.GetFileName(name); var path = Path.Combine(storeDir, safeName); if (!System.IO.File.Exists(path)) return Results.NotFound("Không tìm thấy file."); System.IO.File.Delete(path); return Results.NoContent(); }); app.UseStaticFiles(); app.UseDefaultFiles(); app.UseRouting(); app.MapFallbackToFile("index.html"); app.Run();