using Infrastructure.Extensions; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using System; using System.Globalization; using System.IO; using System.IO.Compression; using System.Net.Http; using System.Security.Cryptography; namespace Infrastructure.Web.Mvc { public class FileController : Controller { private readonly IWebHostEnvironment _host; private readonly IConfiguration _cfg; private readonly IHttpClientFactory _httpClientFactory; public FileController(IWebHostEnvironment host, IConfiguration cfg, IHttpClientFactory httpClientFactory) { this._host = host; this._cfg = cfg; this._httpClientFactory = httpClientFactory; } public IActionResult Upload() { if (Request.Form.Files != null && Request.Form.Files.Count > 0) { var file = Request.Form.Files[0]; var path = this.Save(file); return Content(new { error = 0, url = path }.ToJson()); } return Content(new { error = 1, msg = "未选择文件" }.ToJson()); } public IActionResult Json(string value) { return Content(value); } public string Save(IFormFile file) { if (file is null) { throw new ArgumentNullException(nameof(file)); } var uploadUrl = this._cfg.GetSection("AppSettings").GetValue("upload"); using Stream stream = file.OpenReadStream(); var ext = GetExtension(file.FileName); var md5 = GetFileNameHash(stream); if (string.IsNullOrEmpty(uploadUrl)) { var phicyPath = Path.Combine(this._host.WebRootPath, "upload"); Directory.CreateDirectory(phicyPath); var name = string.Format(CultureInfo.CurrentCulture, "{0}.{1}", md5, ext); var fullName = Path.Combine(phicyPath, name); if (!System.IO.File.Exists(fullName)) { using (FileStream fs = System.IO.File.Create(fullName)) { file.CopyTo(fs); } if (ext == "zip") { var zipDirectory = Path.Combine(phicyPath, md5); Directory.CreateDirectory(Path.Combine(phicyPath, md5)); ZipFile.ExtractToDirectory(fullName, zipDirectory); } } return $"/upload/{name}"; } else { #pragma warning disable CA2000 // 丢失范围之前释放对象 var hc = this._httpClientFactory.CreateClient(); #pragma warning restore CA2000 // 丢失范围之前释放对象 using var form = new MultipartFormDataContent(); stream.Seek(0, SeekOrigin.Begin); var bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); using var fileContent = new ByteArrayContent(bytes); form.Add(fileContent, "file", file.FileName); using var pathContent = new StringContent("dfs"); form.Add(pathContent, "path"); using var outputContent = new StringContent("json"); form.Add(outputContent, "output"); var response = hc.PostAsync(new Uri(uploadUrl), form).Result; var result = response.Content.ReadAsStringAsync().Result; var json = JsonConvert.DeserializeAnonymousType(result, new { url = "", md5 = "", path = "", domain = "", scene = "", size = 0, mtime = 0L, scenes = "", retmsg = "", retcode = -1, src = "" }); return $"/dfs{json.src}"; } } #region private private static string GetExtension(string value) { return value.Substring(value.LastIndexOf('.') + 1).ToLower(CultureInfo.CurrentCulture); } private static string GetFileNameHash(Stream input) { using var hashAlg = SHA256.Create(); byte[] hash = hashAlg.ComputeHash(input); return BitConverter.ToString(hash).Replace("-", string.Empty, true, CultureInfo.CurrentCulture).ToLower(CultureInfo.CurrentCulture); } #endregion private } }