You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET后台事件中立即触发Forge Viewer模型销毁?

问题描述

当前开发Autodesk Forge IDA,现有代码可实现Viewer中模型的销毁与显示:首次点击按钮时从Bucket获取文件并转换为SVF后显示;后续点击时先销毁旧模型再加载新模型。但从Bucket取文件转SVF耗时45-60秒,且当前销毁和显示操作都要等后端Button1_Click事件完全执行完才触发。需求是点击按钮后立即销毁旧模型,让Viewer保持空白,直到后端处理完成再加载新模型。

问题根源

后端Button1_Click是同步执行的方法,Page.ClientScript.RegisterStartupScript会把JS脚本放在页面回发后的响应里,只有当整个后端方法(包括耗时的文件获取、转换)执行完毕,前端才会收到响应并执行销毁和显示的脚本,所以销毁操作被延迟了。

解决方案

把后端的文件处理逻辑改成异步调用,让前端先执行销毁操作,再通过AJAX请求后端处理文件,后端处理完成后返回新模型的URN,前端再加载新模型。具体步骤:

  • 将服务器端按钮替换为HTML按钮,前端点击时先调用destroyModel()销毁旧模型
  • 后端编写异步接口(WebMethod)处理文件获取与SVF转换,返回模型URN
  • 前端通过AJAX调用该接口,等待返回结果后调用showModel()加载新模型
修改后的代码示例

前端页面(default.aspx)

<!-- 替换原服务器按钮为HTML按钮 -->
<button id="loadModelBtn">加载模型</button>
<div id="forgeViewer"></div>

<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script>
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css">
<script src="viewer.js"></script>
<script>
let counter = 1; // 记录点击次数,可根据实际情况调整初始值

document.getElementById('loadModelBtn').addEventListener('click', async function() {
    if (counter !== 1) {
        // 立即销毁旧模型
        destroyModel();
    }

    try {
        // 异步调用后端接口处理文件并获取URN
        const response = await fetch('default.aspx/ProcessModel', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ counter: counter })
        });
        const result = await response.json();
        const objectIdBase64 = result.d;

        // 加载新模型
        showModel(objectIdBase64);
        counter++;
    } catch (error) {
        console.error('模型处理失败:', error);
    }
});
</script>

后端代码(default.aspx.cs)

using System.Web.Services;
using System.Web.Script.Serialization;

public partial class _Default : System.Web.UI.Page
{
    [WebMethod]
    public static string ProcessModel(int counter)
    {
        string objectIdBase64 = string.Empty;
        if (counter == 1)
        {
            // 首次点击:从Bucket获取文件并转换为SVF的代码
            // ... 你的原有逻辑 ...
            // 处理完成后设置objectIdBase64
        }
        else
        {
            // 后续点击:从Bucket获取文件并转换为SVF的代码
            // ... 你的原有逻辑 ...
            // 处理完成后设置objectIdBase64
        }
        return objectIdBase64;
    }
}

viewer.js 优化(增强鲁棒性)

let viewer = null;

function showModel(urn) {
    const options = {
        env: 'AutodeskProduction',
        getAccessToken: getForgeToken
    };
    Autodesk.Viewing.Initializer(options, () => {
        viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer'));
        viewer.start();
        const documentId = 'urn:' + urn;
        Autodesk.Viewing.endpoint.HTTP_REQUEST_HEADERS['If-Modified-Since'] = "Sat, 29 Oct 1994 19:43:31 GMT";
        Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
    });
}

function onDocumentLoadSuccess(doc) {
    const defaultModel = doc.getRoot().getDefaultGeometry();
    viewer.loadDocumentNode(doc, defaultModel);
}

function onDocumentLoadFailure(viewerErrorCode) {
    console.error('模型加载失败 - 错误码:' + viewerErrorCode);
}

function destroyModel() {
    if (viewer) {
        viewer.finish();
        viewer = null;
    }
    Autodesk.Viewing.shutdown();
    // 清空Viewer容器(可选)
    document.getElementById('forgeViewer').innerHTML = '';
}

// 实现你的getForgeToken方法
function getForgeToken(callback) {
    // ... 你的令牌获取逻辑 ...
}
关键说明
  • 前端点击按钮后立即执行destroyModel(),无需等待后端处理,Viewer会立刻空白
  • 后端ProcessModel是异步WebMethod,处理耗时的文件操作,完成后返回URN
  • 前端通过async/await等待后端响应,收到URN后再加载新模型

内容的提问来源于stack exchange,提问作者Siddhesh Nikam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 00:45:32