api
日志中间件需要在包控制管理台安装 Serilog和Serilog.Sinks.File
需要在Program.cs中配置日志工具
using Microsoft.AspNetCore.Mvc;
using PublicHealthUploadFile.PublicMethods;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Serilog;
namespace UploadFile.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class UploadFileController : ControllerBase
{
[HttpPost]
[DisableRequestSizeLimit]//解决上传限制问题
public ActionResult UploadFile()
{
try
{
Log.Information("Beging Upload File.");
if (Request.Form.Files.Count == 0) return BadRequest("Upload Failed: no file.");
var file = Request.Form.Files[0];
if (file.Length < 1) return BadRequest("Upload Failed: file is empty.");
string fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.ToString();
string fileExtension = Path.GetExtension(file.FileName);
//判断可以上传的文件格式 自行设置
const string fileFilt = ".gif|.jpg|.jpeg|.png|.7z|.zip|.rar|.pdf";
if (fileExtension == null)
{
return BadRequest("Upload Failed: 上传的文件没有后缀.");
}
if (fileFilt.IndexOf(fileExtension.ToLower(), StringComparison.Ordinal) <= -1)
{
return BadRequest("Upload Failed: 请上传jpg、png、gif、zip、7z、rar、pdf格式的文件.");
}
//判断文件大小
long length = file.Length;
if (length > 1024 * 1024 * 3) //3M
{
return BadRequest("Upload Failed: 上传的文件不能大于3M.");
}
fileName = fileName.Replace("\"","");
var FileType = Request.Form["Type"].ToString();//类型:根据自己需要选择加不加
var FileCode = Request.Form["CardOrCode"].ToString();//编号: 根据自己需要选择加不加
var FileDate = Request.Form["Date"].ToString();//根据自己需要选择加不加
if (FileType!="身份证"&&(string.IsNullOrEmpty(FileDate)||FileDate=="null")) return BadRequest("Upload Failed: The \"Date\" parameter cannot be empty.");//自定义判断
List<string> filetypeList = new List<string> {"身份证", "签名", "附件"};
if (!filetypeList.Contains(FileType)) return BadRequest("Upload Failed: File types do not match.");//如果FileType 不存在于filetypeList中 则返回异常
string fullPath = GetFullPath(fileName, FileType, FileCode, FileDate);//组合成要存储到的目录
using (var stream = new FileStream(fullPath, FileMode.Create))
{
file.CopyTo(stream);
}
//Program.HostPrefix是在Program.cs文件定义的参数也可自己定义自己服务器访问的地址 实际拼出来的地址就是 ip+port+服务器存储图片的路径
var url = $"{Program.HostPrefix}{ fullPath.Substring(fullPath.IndexOf("pictures/") + "pictures/".Length)}";
Log.Information("End Upload File.");
return Ok(new { message = "Upload Successful.", url });
}
catch (Exception ex)
{
Log.Error("Upload Failed.");
return BadRequest("Upload Failed: " + ex.Message);
}
}
[NonAction]
private string GetFullPath(string fileName, string FileType, string FileCode, string FileDate)
{
string path = "";
// 保存路径 pictures/IdentityCard/身份证.jpg pictures/Signature/年/身份证/日期/****.jpg
int year = 0; string date = "";
if (!string.IsNullOrEmpty(FileDate))
{
DateTime dt = DateTime.Parse(FileDate); year = dt.Year; date = dt.ToString("yyyy-MM-dd");
}
string file1 = fileName.Replace(fileName.Remove(fileName.LastIndexOf(".")), Guid.NewGuid().ToString("N"));
FileCode= Encrypt.EncryptText(FileCode);
switch (FileType)
{
case "身份证":path = CreatePath($"IdentityCard/{FileCode}/") + file1; break;
case "签名":DataIsNull(year); path = CreatePath($"Signature/{year}/{FileCode}/{date}/") + file1; break;
case "附件": DataIsNull(year); path = CreatePath($"Annex/{year}/{date}/") + file1; break;
default:
path = CreatePath($"Other/Year/{date}/") + file1; break;
}
return path;
}
[NonAction]
private void DataIsNull(int year) {
if (year == 0) throw new Exception("日期参数未传参。");
}
[NonAction]
private string CreatePath(string path)
{
string basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取网站运行根目录
string picturesPath = basePath + "/pictures/";
picturesPath += path;
if (!Directory.Exists(picturesPath))
{
Directory.CreateDirectory(picturesPath);
}
return picturesPath;
}
}
}
在Program.cs中配置日志组件
在mian函数中添加以下代码
using Serilog;
using Serilog.Events;
public static int Main(string[] args)
{
//CreateHostBuilder(args).Build().Run();
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()//最小的输出单位是Debug级别的
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)//将Microsoft前缀的日志的最小输出级别改成Information
.Enrich.FromLogContext()
.WriteTo.File(@"./logs/log.txt", rollingInterval: RollingInterval.Day).CreateLogger();
try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
在Program.cs中配置解决文件上传限制
.UseKestrel(options=> {
options.Limits.MaxRequestBodySize = null;
});
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
.UseUrls("http://*:365")
.UseKestrel(options=> {
options.Limits.MaxRequestBodySize = null;
});
});
在Startup.cs 中的ConfigureServices中 在最前边添加以下代码,解决文件上传限制问题
services.Configure<FormOptions>(x =>
{
x.ValueLengthLimit = int.MaxValue;
x.ValueCountLimit = int.MaxValue;
x.MultipartBodyLengthLimit = long.MaxValue;
x.MultipartBoundaryLengthLimit = int.MaxValue;
x.BufferBodyLengthLimit = long.MaxValue;
x.BufferBody = true;
x.MemoryBufferThreshold = int.MaxValue;
x.KeyLengthLimit = int.MaxValue;
x.MultipartHeadersLengthLimit = int.MaxValue;
x.MultipartHeadersCountLimit = int.MaxValue;
});