【问题标题】:Autodesk Forge .NET SDK GetObject function and downloading files from BIM 360 Docs hubAutodesk Forge .NET SDK GetObject 功能和从 BIM 360 Docs 中心下载文件
【发布时间】:2020-05-06 08:03:47
【问题描述】:

我在使用 Forge .NET SDK 中的 GetObject 函数从 BIM 360 Docs 中心下载文件时遇到问题。

这是我的 jQuery ajax 调用(客户端):

function downloadFile(storageUrl, displayName) {
jQuery.ajax({
    url: '/api/forge/datamanagement/download?' + $.param({ storageUrl: storageUrl }),
    success: function (res) {
        // create a blob url representing the data
        var blob = new Blob([res]);
        var url = window.URL.createObjectURL(blob);
        // attach blob url to anchor element with download attribute
        var anchor = document.createElement('a');
        anchor.setAttribute('href', url);
        anchor.setAttribute('download', displayName);
        anchor.click();
        window.URL.revokeObjectURL(url);
    }
});

这是我的 .NET C# 对应的控制器功能(服务器端):

    [HttpGet]
    [Route("api/forge/datamanagement/download")]
    public async Task<dynamic> GetObject(string storageUrl)
    {
        Credentials = await Credentials.FromSessionAsync(base.Request.Cookies, Response.Cookies);
        if (Credentials == null) { return null; }

        ObjectsApi objectsApi = new ObjectsApi();
        objectsApi.Configuration.AccessToken = Credentials.TokenInternal;

        string[] idParams = storageUrl.Split('/');
        string bucketKey = idParams[6];
        string objectName = idParams[8];
        if (objectName.Contains("?"))
            objectName = objectName.Split("?")[0];

        dynamic obj = await objectsApi.GetObjectAsync(bucketKey, objectName);

        if (obj is FileStream)
            return File(obj, "application/octet-stream");

        if (obj is MemoryStream ms)
        {
            FileStream fs = new FileStream(Path.Combine(Path.GetTempPath(), objectName), FileMode.Create, FileAccess.ReadWrite);
            ms.CopyTo(fs);
            ms.Position = 0;
            fs.Position = 0;
            return File(fs, "application/octet-stream");
        }

        return null;
    }

问题在于从 GetObjectAsync 调用获得结果之后:

  • 如果它返回一个FileStream(如.txt文件),没有问题,下载的文件是正确的。
  • 如果它返回一个 MemoryStream(如 .json 和 .rvt 文件),我将它写入 FileStream 然后返回它。 它仅适用于 .json 文件。对于 .rvt 文件,下载的文件已损坏,Revit 无法打开。

奇怪的是:

  • 损坏的文件大约是“真实”/“正确”文件的 2 倍。
  • 将 MemoryStream 复制到 FileStream 时,在我的服务器临时文件夹中临时创建的 Revit 文件是正确的。

我在这里错过了什么?

感谢您的帮助。

马克西姆

【问题讨论】:

  • 我可以重现这个问题。如果检查响应,它的长度看起来是正确的。将流转换为 blob 后长度开始出错。 Forge的下载文件看起来没有问题,正如你我测试的那样,流可以保存到服务器端的正确文件中。我将深入研究如何使其发挥作用。

标签: autodesk-forge autodesk-data-management autodesk-bim360


【解决方案1】:

这里可能存在编码问题,因为您提到文件大 2 倍。

无论如何,我建议您改用“代理”方法。让我解释一下:GetObjectAsync 会将整个文件下载到您的服务器,这可能很大并分配大量内存。即使在发送给客户端之前保存在本地,仍然分配磁盘资源……

代理方法只会从 Forge 获取数据块并将每个数据块流式传输到客户端。有不同的实现方式,可能this other answer 是一个开始。

【讨论】:

    猜你喜欢
    • 2017-09-05
    • 2019-12-18
    • 2022-12-15
    • 2021-12-09
    • 2020-06-24
    • 2018-05-29
    • 2020-12-29
    • 2018-11-23
    • 2021-02-17
    相关资源
    最近更新 更多