如何用C#插件在模型驱动应用功能区按钮实现本地文件下载?
Dataverse插件无法将文件写入用户本地目录的解决方案
问题描述
我已经在插件中集成了从Dataverse表下载文件并执行自动化任务的代码:
private static byte[] DownloadFile(IOrganizationService orgService, string entityName, Guid recordGuid, string fileAttributeName) { var initializeFileBlocksDownloadRequest = new InitializeFileBlocksDownloadRequest { Target = new EntityReference(entityName, recordGuid), FileAttributeName = fileAttributeName }; var initializeFileBlocksDownloadResponse = (InitializeFileBlocksDownloadResponse)orgService.Execute(initializeFileBlocksDownloadRequest); DownloadBlockRequest downloadBlockRequest = new DownloadBlockRequest { FileContinuationToken = initializeFileBlocksDownloadResponse.FileContinuationToken }; var downloadBlockResponse = (DownloadBlockResponse)orgService.Execute(downloadBlockRequest); return downloadBlockResponse.Data; }
完成自动化任务后,我尝试用File.WriteAllBytes(<File_Name>, downloadBlockResponse.Data);把文件保存到触发插件的用户本地下载目录,但没有效果,求替代方案或直接实现方法?
核心原因
Dataverse插件运行在服务器端(Dynamics 365云端服务器或本地部署服务器),它没有权限访问触发用户的本地文件系统——File.WriteAllBytes操作只会把文件写入插件运行所在的服务器磁盘,而非用户的本地电脑,这就是你看不到文件的根本原因。
可行解决方案
1. 改用客户端触发逻辑(推荐)
把文件下载逻辑从服务器端插件转移到客户端代码:
- Power Apps画布应用:使用
Download函数直接获取文件内容,触发浏览器下载到用户本地目录。 - Power Automate:添加「下载文件」动作,将Dataverse文件内容输出到用户的OneDrive,或通过桌面流直接保存到本地。
- 自定义Web资源:用JavaScript调用Web API获取文件内容,前端生成下载链接让用户手动保存。
2. 服务器端暂存+客户端通知
如果必须保留服务器端自动化任务:
- 将处理后的文件上传回Dataverse(比如新建注释记录或自定义文件实体)。
- 触发通知:通过邮件发送文件下载链接,或在Dataverse中创建提示记录,让用户自行从Dataverse下载到本地。
3. 修复多块文件下载逻辑
你的DownloadFile方法仅支持单块文件(≤4MB),如果文件大于4MB,Dataverse会拆分存储,需循环下载所有块并拼接:
private static byte[] DownloadFile(IOrganizationService orgService, string entityName, Guid recordGuid, string fileAttributeName) { var initializeRequest = new InitializeFileBlocksDownloadRequest { Target = new EntityReference(entityName, recordGuid), FileAttributeName = fileAttributeName }; var initializeResponse = (InitializeFileBlocksDownloadResponse)orgService.Execute(initializeRequest); List<byte> fileBytes = new List<byte>(); string continuationToken = initializeResponse.FileContinuationToken; while (!string.IsNullOrEmpty(continuationToken)) { var downloadRequest = new DownloadBlockRequest { FileContinuationToken = continuationToken }; var downloadResponse = (DownloadBlockResponse)orgService.Execute(downloadRequest); fileBytes.AddRange(downloadResponse.Data); continuationToken = downloadResponse.FileContinuationToken; } return fileBytes.ToArray(); }
内容的提问来源于stack exchange,提问作者Satoko EntertainMent
相关产品推荐
相关产品推荐

