将图片保存到数据库可能不是一个好主意,尤其是图片多的时候。但是,至少也多了一种选项。
首先,修改appsettings.json,增加一个配置项,use_db_to_store_image
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"AppSettings": {
"db_type": "mysql",
"connStr": "Server=localhost;Port=3306;Database=db_blog;User=root;Password=123456;Charset=utf8mb4;SslMode = none;allowPublicKeyRetrieval=true",
"use_db_to_store_image":"1"
}
}
Program.cs
using core_admin.utils;
using core_admin.db;
using UEditorNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
Global_Values.connStr = WebHelper.get_item("connStr");
//控制是否使用数据库存储图片等上传的数据,1 或者 0
Global_Values.use_db_to_store_image = WebHelper.get_item("use_db_to_store_image");
AutofacConfig.Register();
var builder = WebApplication.CreateBuilder(args);
//这里控制上传文件的大小
builder.Services.Configure<FormOptions>(x =>
{
x.ValueLengthLimit = int.MaxValue;
x.MultipartBodyLengthLimit = int.MaxValue; // In case of multipart
x.MemoryBufferThreshold = Int32.MaxValue;
});
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSession();
builder.Services.AddUEditorService();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseSession();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
我这里控制上传的地方有两处,一处是UploadController.cs,
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using core_admin.utils;
using Autofac;
using core_admin.db;
using core_admin.i;
using core_admin.m;
namespace core_admin.Controllers
{
public class UploadController : Controller
{
[HttpGet]
public IActionResult Index()
{
return View();
}
[HttpGet]
public string RemoveJ(string upload_path, string upload_file)
{
var path = System.IO.Path.Combine(upload_path, upload_file);
var real_path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot", path);
if (System.IO.File.Exists(real_path))
{
try
{
System.IO.File.Delete(real_path);
}
catch { }
}
return "success";
}
//用于图片的显示
[HttpGet]
public IActionResult ShowImage(int id)
{
using (var scope = AutofacConfig.Container.BeginLifetimeScope())
{
IBlob c = scope.Resolve<IBlob>();
tb_blob item = c.Get(id);
if (item != null)
{
byte[] bytes = item.blob_content;
string ext = MimeHelper.getMimeTypeByExt(item.file_extention);
return new FileContentResult(bytes, ext);
}
string wwwroot_path = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
string path = System.IO.Path.Combine(wwwroot_path, "img/404.webp");
byte[] bytes2 = System.IO.File.ReadAllBytes(path);
string ext2 = "image/webp";
return new FileContentResult(bytes2, ext2);
}
}
//上传图片
[HttpPost]
public string Upload()
{
MyResult result = new MyResult();
try
{
var form = Request.Form;
Hashtable hash = new Hashtable();
string upload_path = "uploads/files/";
if (form.ContainsKey("upload_path"))
{
upload_path = form["upload_path"];
}
IFormFileCollection cols = Request.Form.Files;
if (cols == null || cols.Count == 0)
return "file not selected";
foreach (IFormFile file in cols)
{
// 根据参数判断是否存储图片或文件到数据库
if (Global_Values.use_db_to_store_image == "1")
{
string extension = System.IO.Path.GetExtension(file.FileName);
Stream ist = file.OpenReadStream();
byte[] bytes = new byte[ist.Length];
ist.Read(bytes, 0, bytes.Length);
ist.Close();
ist = file.OpenReadStream();
DateTime createDate = ImageUtils.getCreateDate2(ist);
hash.Add("createDate", DateTimeUtilities.toYmdhms(createDate));
ist.Close();
ist = file.OpenReadStream();
string md5 = Encryp.GetFileMD5A(ist);
ist.Close();
hash.Add("md5", md5);
long blob_id = 0;
using (var scope = AutofacConfig.Container.BeginLifetimeScope())
{
IBlob c = scope.Resolve<IBlob>();
tb_blob item = c.GetByMd5(md5);
if (item == null)
{
item = new tb_blob();
item.blob_content = bytes;
item.create_date = createDate;
item.file_extention = extension;
item.md5 = md5;
blob_id = c.Insert(item);
}
else
{
blob_id = item.id;
}
hash.Add("id", blob_id.ToString());
hash.Add("file", "/Upload/ShowImage?id=" + blob_id.ToString());
}
}
else
{
var new_path = Guid.NewGuid() + System.IO.Path.GetExtension(file.FileName);
new_path = Path.Combine(upload_path, new_path);
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot", new_path);
string? a_dir = System.IO.Path.GetDirectoryName(path);
if (a_dir != null && !System.IO.Directory.Exists(a_dir))
{
System.IO.Directory.CreateDirectory(a_dir);
}
using (var stream = new FileStream(path, FileMode.Create))
{
file.CopyTo(stream);
hash.Add("file", "/" + new_path);
}
DateTime createDate = ImageUtils.getCreateDate(path);
hash.Add("createDate", DateTimeUtilities.toYmdhms(createDate));
string md5 = Encryp.GetFileMD5(path);
hash.Add("md5", md5);
}
}
result.data = hash;
result.result = "success";
}
catch (Exception ex)
{
result.err_msg = ex.Message;
result.result = "error";
}
return JsonConvert.SerializeObject(result);
}
}
}
另外一个是?UEditorNetCore 的上传代码,原先是项目引用的,现在要修改,直接注释掉项目引用,下载?UEditorNetCore 的源码,放在 code 下,修改里面的? UEditorNetCore\Handlers\UploadHandler.cs
using System;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Http;
using core_admin.utils;
using core_admin.i;
using core_admin.db;
using core_admin.m;
using Autofac;
namespace UEditorNetCore.Handlers
{
public class UploadHandler : Handler
{
public UploadConfig UploadConfig { get; private set; }
public UploadResult Result { get; private set; }
public UploadHandler(HttpContext context, UploadConfig config)
: base(context)
{
this.UploadConfig = config;
this.Result = new UploadResult() { State = UploadState.Unknown };
}
public override void Process()
{
byte[] uploadFileBytes = null;
string uploadFileName = null;
string md5 = "";
DateTime createDate = DateTime.Parse("1900-01-01");
string extension = ".jpg";
if (UploadConfig.Base64)
{
uploadFileName = UploadConfig.Base64Filename;
uploadFileBytes = Convert.FromBase64String(Request.Form[UploadConfig.UploadFieldName]);
}
else
{
var file = Request.Form.Files[UploadConfig.UploadFieldName];
uploadFileName = file.FileName;
extension = System.IO.Path.GetExtension(uploadFileName);
if (!CheckFileType(uploadFileName))
{
Result.State = UploadState.TypeNotAllow;
WriteResult();
return;
}
if (!CheckFileSize((int)file.Length))
{
Result.State = UploadState.SizeLimitExceed;
WriteResult();
return;
}
uploadFileBytes = new byte[file.Length];
try
{
file.OpenReadStream().Read(uploadFileBytes, 0, (int)file.Length);
}
catch (Exception)
{
Result.State = UploadState.NetworkError;
WriteResult();
}
Stream ist = file.OpenReadStream();
md5 = Encryp.GetFileMD5A(ist);
ist.Close();
if(ImageUtils.isImageByFileName(uploadFileName)){
try {
ist= file.OpenReadStream();
createDate = ImageUtils.getCreateDate2(ist);
ist.Close();
} catch (Exception ex3){
Console.WriteLine(ex3.Message);
Console.WriteLine(ex3.StackTrace);
}
}
}
Result.OriginFileName = uploadFileName;
var savePath = PathFormatter.Format(uploadFileName, UploadConfig.PathFormat);
var localPath = Path.Combine(Config.WebRootPath, savePath);
try
{
if(Global_Values.use_db_to_store_image=="1"){
long blob_id = 0;
using (var scope = AutofacConfig.Container.BeginLifetimeScope())
{
IBlob c = scope.Resolve<IBlob>();
tb_blob item = c.GetByMd5(md5);
if(item==null){
item = new tb_blob();
item.blob_content = uploadFileBytes;
item.create_date = createDate;
item.file_extention = extension;
item.md5 = md5;
blob_id = c.Insert(item);
//Console.WriteLine("data inserted ");
} else {
blob_id = item.id;
//Console.WriteLine("data already exists ");
}
Result.Url = "Upload/ShowImage?id="+blob_id.ToString();
}
} else {
if (!Directory.Exists(Path.GetDirectoryName(localPath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(localPath));
}
File.WriteAllBytes(localPath, uploadFileBytes);
Result.Url = savePath;
}
Result.State = UploadState.Success;
}
catch (Exception e)
{
Result.State = UploadState.FileAccessError;
Result.ErrorMessage = e.Message;
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
finally
{
WriteResult();
}
}
private void WriteResult()
{
this.WriteJson(new
{
state = GetStateMessage(Result.State),
url = Result.Url,
title = Result.OriginFileName,
original = Result.OriginFileName,
error = Result.ErrorMessage
});
}
private string GetStateMessage(UploadState state)
{
switch (state)
{
case UploadState.Success:
return "SUCCESS";
case UploadState.FileAccessError:
return "文件访问出错,请检查写入权限";
case UploadState.SizeLimitExceed:
return "文件大小超出服务器限制";
case UploadState.TypeNotAllow:
return "不允许的文件格式";
case UploadState.NetworkError:
return "网络错误";
}
return "未知错误";
}
private bool CheckFileType(string filename)
{
var fileExtension = Path.GetExtension(filename).ToLower();
return UploadConfig.AllowExtensions.Select(x => x.ToLower()).Contains(fileExtension);
}
private bool CheckFileSize(int size)
{
return size < UploadConfig.SizeLimit;
}
}
public class UploadConfig
{
/// <summary>
/// 文件命名规则
/// </summary>
public string PathFormat { get; set; }
/// <summary>
/// 上传表单域名称
/// </summary>
public string UploadFieldName { get; set; }
/// <summary>
/// 上传大小限制
/// </summary>
public int SizeLimit { get; set; }
/// <summary>
/// 上传允许的文件格式
/// </summary>
public string[] AllowExtensions { get; set; }
/// <summary>
/// 文件是否以 Base64 的形式上传
/// </summary>
public bool Base64 { get; set; }
/// <summary>
/// Base64 字符串所表示的文件名
/// </summary>
public string Base64Filename { get; set; }
}
public class UploadResult
{
public UploadState State { get; set; }
public string Url { get; set; }
public string OriginFileName { get; set; }
public string ErrorMessage { get; set; }
}
public enum UploadState
{
Success = 0,
SizeLimitExceed = -1,
TypeNotAllow = -2,
FileAccessError = -3,
NetworkError = -4,
Unknown = 1,
}
}
完整的代码在 这里 可以下载 。
|