C#中IForm类型无法通过ABP Generate Proxy生成代理(附解决方案)

85 篇文章 0 订阅

ABP处理非结构化数据的方式:分布式文件系统minio_董厂长的博客-CSDN博客这两天再搞pdf上传的事情。一开始想法是。前端传Base64块,后端接受,存服务器,相关实体存路径。后来实际看项目发现并没有产品经理所谓的“公司网盘”这个东西。。。然后去ABP官网看了看关于非结构化数据存储的东西。原来放在了基础设施层。ABP框架为BLOB提供了抽象,并提供了一些可以轻松集成到的预构建存储提供程序. 好处;你可以通过几行配置轻松的集成你喜欢的BLOB存储提供程序.你可以轻松的更改BLOB存储,而不用改变你的应用程序代码.如果你想创建可重用的应用程序模块,无需假设https://blog.csdn.net/dongnihao/article/details/124936500问题是这样的,我后端想接受一个文件,很自然的写的类型是 IFormFile file。然后又很自然的使用ABP CLI生成我需要的前端代理。

 

然后,就,代理报错,显示无法导出类型 IFormFile。

Incorrect proxy generated for file upload API · Issue #6384 · abpframework/abp · GitHubhttps://github.com/abpframework/abp/issues/6384

 同样的,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。等拿的时候拼接一下就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董厂长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值