You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iot/projects/Infrastructure/Web/Mvc/FileController.cs

166 lines
6.2 KiB

using Infrastructure.Extensions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Minio;
using System;
using System.Collections.Generic;
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 fileserver = this._cfg.GetSection("AppSettings").GetValue<string>("fileserver");
var path = string.Empty;
try
{
if (string.IsNullOrEmpty(fileserver))
{
path = UploadLocalServer(file);
}
else
{
if (fileserver == "minio")
{
path = UploadMinIO(file);
}
}
}
catch (Exception ex)
{
return Content(new { error = 3, msg = ex.Message }.ToJson());
}
if (string.IsNullOrEmpty(path))
{
return Content(new { error = 2, msg = "文件存储失败" }.ToJson());
}
return Content(new { error = 0, url = path }.ToJson());
}
return Content(new { error = 1, msg = "未选择文件" }.ToJson());
}
public IActionResult Json(string value)
{
return Content(value);
}
private string UploadLocalServer(IFormFile file)
{
using Stream stream = file.OpenReadStream();
var ext = GetExtension(file.FileName);
var md5 = GetFileNameHash(stream);
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}";
}
private string UploadMinIO(IFormFile file)
{
using var stream = file.OpenReadStream();
var ext = Path.GetExtension(file.FileName);
var md5 = GetFileNameHash(stream);
var name = $"{md5}{ext}";
var endpoint = this._cfg["minio:endpoint"];
var accessKey = this._cfg["minio:accessKey"];
var secretKey = this._cfg["minio:secretKey"];
var bucketName = "upload";
var minio = new MinioClient(endpoint, accessKey, secretKey);//.WithSSL();
bool found = minio.BucketExistsAsync(bucketName).Result;
if (!found)
{
minio.MakeBucketAsync(bucketName);
var policyJson = new
{
Version = "2012-10-17",
Statement = new List<object>{
new {
Effect="Allow",
Principal=new {
AWS=new List<object>{"*"}
},
Action=new List<object>{"s3:GetBucketLocation", "s3:ListBucket", "s3:ListBucketMultipartUploads"},
Resource="arn:aws:s3:::upload"
}, new {
Effect= "Allow",
Principal=new {
AWS=new List<object>{"*"}
},
Action=new List<object>{"s3:AbortMultipartUpload", "s3:DeleteObject", "s3:GetObject", "s3:ListMultipartUploadParts", "s3:PutObject"},
Resource=new List<object>{"arn:aws:s3:::upload/*"}
}
}
};
minio.SetPolicyAsync(bucketName, policyJson.ToJson());
}
try
{
var result = minio.StatObjectAsync(bucketName, name).Result;
}
catch (AggregateException ex)
{
ex.PrintStack();
stream.Position = 0;
new FileExtensionContentTypeProvider().Mappings.TryGetValue(ext, out string contenttype);
minio.PutObjectAsync(bucketName, name, stream, stream.Length, contenttype);
}
var path = $"/{bucketName}/{name}";
return $"/dfs{path}";
}
#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
}
}