简体   繁体   English

将 PDF ( > 4 MB) 上传到 D365 CRM 中的文件数据类型

[英]Upload PDF ( > 4 MB) to File datatype in D365 CRM

I'm trying to upload a PDF file to a CRM record.我正在尝试将 PDF 文件上传到 CRM 记录。 I've used a File type field in the entity that can hold my uploaded file.我在实体中使用了一个文件类型字段来保存我上传的文件。 I've done this by using this code:我使用以下代码完成了此操作:

UploadBlockRequest blockRequest = new UploadBlockRequest();
blockRequest.BlockData = Convert.FromBase64String(documentBody);
blockRequest.BlockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));
blockRequest.FileContinuationToken = initResponse.FileContinuationToken;

var blockResponse = (UploadBlockResponse)service.Execute(blockRequest);

It is working fine for PDF files that are under 4 MB.它适用于 PDF 个小于 4 MB 的文件。 However, If I try to upload a PDF that's more than 4 MB, I get the following error:但是,如果我尝试上传超过 4 MB 的 PDF,我会收到以下错误:

Invalid file chunk size: 4 MB.无效的文件块大小:4 MB。 Maximum chunk size supported: 4 MB.支持的最大块大小:4 MB。

Is there a way to upload large PDF files to CRM record?有没有办法将 PDF 大文件上传到 CRM 记录?

using (var stream = new MemoryStream(Convert.FromBase64String(Base64)))
                    {
                        InitializeFileBlocksUploadRequest initializeUploadRequest = new InitializeFileBlocksUploadRequest();
                        initializeUploadRequest.FileAttributeName = "my_fileTypeField";
                        initializeUploadRequest.FileName = "Test.pdf";
                        initializeUploadRequest.Target = new EntityReference("my_entity", new Guid("my_guid"));

                        var initializeUploadResponse = (InitializeFileBlocksUploadResponse)service.Execute(initializeUploadRequest);
                        var uploadRequest = new UploadBlockRequest { FileContinuationToken = initializeUploadResponse.FileContinuationToken };

                        const int blockSize = 4194304; // 4MB
                        int byteCount;
                        var blockList = new List<string>();

                        do
                        {
                            
                            //uploadRequest.BlockData = Convert.FromBase64String(documentBody);
                            byteCount = stream.Read(uploadRequest.BlockData, 0, blockSize);
                            uploadRequest.BlockId = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
                            service.Execute(uploadRequest);
                            blockList.Add(uploadRequest.BlockId);
                            Console.WriteLine(size + " == " + blockSize);
                        } while (size == blockSize);

                        var commitRequest = new CommitFileBlocksUploadRequest
                        {
                            BlockList = blockList.ToArray(),
                            FileContinuationToken = initializeUploadResponse.FileContinuationToken,
                            FileName = initializeUploadRequest.FileName,
                            MimeType = "application/pdf"
                        };
                        var commitResponse = (CommitFileBlocksUploadResponse)service.Execute(commitRequest);
                    }

The UploadBlockRequest is one piece in the file upload procedure. UploadBlockRequest是文件上传过程中的一部分。 You need 3 distinct requests:您需要 3 个不同的请求:

  1. InitializeFileBlocksUploadRequest
  2. UploadBlockRequest
  3. CommitFileBlocksUploadRequest

The UploadBlockRequest can hold a chunk of 4 MB of data at a maximum. UploadBlockRequest最多可以容纳 4 MB 的数据块。 Your file can be as large as 128 MB and it can be uploaded using multiple upload requests.您的文件可以大到 128 MB,并且可以使用多个上传请求上传。

A basic upload method could look like this:一个基本的上传方法可能如下所示:

private Guid UploadFile
    (
        FileStream stream,
        string fileName,
        string mimeType,
        EntityReference target,
        string fileAttributeName,
        IOrganizationService organizationService
    )
{
    var initializeUploadRequest = new InitializeFileBlocksUploadRequest
    {
        FileAttributeName = fileAttributeName,
        FileName = fileName,
        Target = target
    };

    var initializeUploadResponse = (InitializeFileBlocksUploadResponse)organizationService.Execute(initializeUploadRequest);
    var uploadRequest = new UploadBlockRequest { FileContinuationToken = initializeUploadResponse.FileContinuationToken };

    const int blockSize = 4194304; // 4 MB
    int byteCount;
    var blockList = new List<string>();

    do
    {
        byteCount = stream.Read(uploadRequest.BlockData, 0, blockSize);
        uploadRequest.BlockId = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
        organizationService.Execute(uploadRequest);
        blockList.Add(uploadRequest.BlockId);
    } while (byteCount == blockSize);

    var commitRequest = new CommitFileBlocksUploadRequest
    {
        BlockList = blockList.ToArray(),
        FileContinuationToken = initializeUploadResponse.FileContinuationToken,
        FileName = initializeUploadRequest.FileName,
        MimeType = mimeType
    };

    var commitResponse = (CommitFileBlocksUploadResponse)organizationService.Execute(commitRequest);
    return commitResponse.FileId;
}

The method uploads the file and returns the ID of the file.该方法上传文件并返回文件的ID。

I modified the example from Henk a little because I was having the error:我稍微修改了 Henk 的示例,因为我遇到了错误:

Buffer cannot be null缓冲区不能是 null

However, I believe my approach won't work for big files.但是,我相信我的方法不适用于大文件。 I have tested this approach for files up to 5MB sucessfully.我已经成功地为最大 5MB 的文件测试了这种方法 Files bigger than that will need to be uploaded using the approach from Henk.比这更大的文件需要使用 Henk 的方法上传。 I'm not a coding genius myself to figure out the way Henk's example can be improved to avoid the bug.我自己并不是一个编码天才,无法弄清楚如何改进 Henk 的示例以避免该错误。

private Guid UploadFile(byte[] fileBytes, string fileName, string mimeType, EntityReference target, string fileAttributeName, IOrganizationService ctx)
    {
        var initializeUploadRequest = new InitializeFileBlocksUploadRequest
        {
            FileAttributeName = fileAttributeName,
            FileName = fileName,
            Target = target
        };


        var initializeUploadResponse = (InitializeFileBlocksUploadResponse)ctx.Execute(initializeUploadRequest);
        var uploadRequest = new UploadBlockRequest
        {
            FileContinuationToken = initializeUploadResponse.FileContinuationToken,
            BlockData = fileBytes,
            BlockId = Convert.ToBase64String(Guid.NewGuid().ToByteArray())
        };


        var blockList = new List<string>();

        ctx.Execute(uploadRequest);
        blockList.Add(uploadRequest.BlockId);


        var commitRequest = new CommitFileBlocksUploadRequest
        {
            BlockList = blockList.ToArray(),
            FileContinuationToken = initializeUploadResponse.FileContinuationToken,
            FileName = initializeUploadRequest.FileName,
            MimeType = mimeType
        };

        var commitResponse = (CommitFileBlocksUploadResponse)ctx.Execute(commitRequest);
        return commitResponse.FileId;
    }
}

I do work with a Byte Array as the input instead of a stream, as in my Solution I'm downloading a file from 1 entity (which is returned as a byte[]), to upload it in another entity.我确实使用字节数组作为输入而不是 stream,因为在我的解决方案中,我正在从 1 个实体(作为字节 [] 返回)下载文件,以将其上传到另一个实体中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将现有实体记录(竞争对手)关联到新记录(机会)crm d365 On create message - Associate existing entity records (competitor) to new record (opportunity) crm d365 On create message D365 中来自 IServiceProvider 的自定义服务 - Custom services from IServiceProvider in D365 在业务流程变更上触发插件(D365 / 9.1) - Trigger Plugin on Business Process flow Change (D365/9.1) D365 C#-检索多个并且更新非常慢 - D365 C# - Retrieve Multiple and Updating Very Slow 如何通过 C# 连接到 Azure D365 Odata - How to connect to Azure D365 Odata via C# D365 Business Central,我们需要使用C#代码将记录创建到Items中 - D365 Business Central, we need to create records into Items using C# code D365(本地):使用QueryExpression用“ LinkedFrom”实体字段更新“ LinkedTo”实体字段 - D365 (On-Prem): Update 'LinkedTo“ Entity field with ”LinkedFrom" Entity field using QueryExpression 从相交实体 D365 C# 获取相关实体 - Getting related entities from intersect entity D365 C# 当我只有跟踪程序以测试执行时,D365 v9 Online上的插件失败 - Plugin Failing on D365 v9 Online when I just have tracers to test execution Dynamics CRM-&gt; Azure Blob存储-&gt; 40 MB文件上传会出现超时错误。 注释的PostCreate上的自定义插件 - Dynamics CRM--> Azure Blob Storage--> 40 MB file upload gives Timeout Error. Custom Plugin on PostCreate of annotation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM