ABP处理非结构化数据的方式:分布式文件系统minio_董厂长的博客-CSDN博客这两天再搞pdf上传的事情。一开始想法是。前端传Base64块,后端接受,存服务器,相关实体存路径。后来实际看项目发现并没有产品经理所谓的“公司网盘”这个东西。。。然后去ABP官网看了看关于非结构化数据存储的东西。原来放在了基础设施层。ABP框架为BLOB提供了抽象,并提供了一些可以轻松集成到的预构建存储提供程序. 好处;你可以通过几行配置轻松的集成你喜欢的BLOB存储提供程序.你可以轻松的更改BLOB存储,而不用改变你的应用程序代码.如果你想创建可重用的应用程序模块,无需假设https://blog.csdn.net/dongnihao/article/details/124936500问题是这样的,我后端想接受一个文件,很自然的写的类型是 IFormFile file。然后又很自然的使用ABP CLI生成我需要的前端代理。
然后,就,代理报错,显示无法导出类型 IFormFile。
同样的,swagger接口测试时候显示可以上传没毛病,甚至可以多个上传文件。但是在Angular里显示的无法使用IFormFile类型。(忽然觉得还是JS比较自由自在)
评论中的解决方案是不使用Proxy中生成的服务,而是自己写http请求。这样做法相当不好。首先你跑到线上环境还是要重新跑proxy的,生产环境爆错直接挂。第二,服务器地址或者端口会变,这样到时候错了还要手动去改端口,很麻烦。
直接抛我的解决方案:
I also meet this issue,so there is an alternative solutions. when you upload a file, don't use "IFromFile" type. try to create another Dto, and one of its properties is " public string fileContent{ get;set; }". like this
public class ReportsUploadDto
{
public string Name
{
get;
set;
}
public string FileType
{
get;
set;
}
public string LinkedCourseId
{
get;
set;
}
public string FileContent
{
get;
set;
}
}
so in frontend(i use angular). generate a proxy base on ABP, than follow the "ReportsUploadDto" type. After that, the string obtained from Base64 should be converted into byte and stored in minio.
我的comment意思是,不要传文件格式。另外建一个Dto(文件传输对象)。文件内容以Base64 string放进去,放到FileContent属性内。这样完整的传到后端,再做Convert解码为流文件。(因为minio接受流文件),如果你使用其他分布式文件系统,按要求来就行了,二进制流是万能的。
public async Task<List<ThirdPartReportsDto>> UploadThirdPartReportsListWithByteForm(ThirdPartReportsUploadDto[] files)
{
// List上传
var output = new List<ThirdPartReportsDto>();
foreach (var file in files)
{
var id = Guid.NewGuid();
var newFile = new ThirdPartReportsEntity(id, 0, file.FileType, CurrentTenant.Id, file.Name, file.LinkedCourseId);
var created = await _repository.InsertAsync(newFile);
var base64Str = file.FileContent.Split("base64,")[1];
byte[] byteResult = Convert.FromBase64String(base64Str);
await _blobContainer.SaveAsync(id.ToString(), byteResult, true).ConfigureAwait(false);
output.Add(ObjectMapper.Map<ThirdPartReportsEntity, ThirdPartReportsDto>(newFile));
}
return output;
}
注意,一开始转码报错,我看了看base64的文件头要掐掉,不然符合格式。
var base64Str = file.FileContent.Split("base64,")[1];
另外一些细节:存文件信息到数据库中,一定得按Guid做任何增删改查操作,因为你永远不知道用户会不会做出脑溢血操作,比如同文件名。
2022.6.1 复盘
获取文件时候显示文件格式损坏,查了查,原来是存的时候吧header头信息给删了,加回去就行了。
ThirdPartReportsUploadDto returnFile = new ThirdPartReportsUploadDto();
returnFile.FileContent ="data:application/pdf;base64,"+myFileBase64;
2022.6.2 新的思考
如果突然有一天,我想存任意格式的文件,那么这种写死的Base64 header就不能用了。
🤔那就在存文件时候对Entity加一个属性 “FileHeaderInformation”,存入结构型数据库。
这样分布式系统存文件的content,结构型数据库存文件的header。等拿的时候拼接一下就可以了。