SDK 快速接入 C#

1. SDK接入概要说明

C# SDK适用于.net standard 2.0 标准以上版本, 截止目前,以.net 8.0最佳。可以下载对应的demo,参考如何使用SDK接入处理。

2. 安装说明

SDK接入有3种安装方式,操作分别如下,可按需选其中一种方式安装:

  • 使用dotnet cli安装:

    打开命令行并切换到包含项目文件的目录,运行以下下命令安装 :

    dotnet add package YunApiSDK
  • 使用包管理器控制台安装:

    在 Visual Studio 中打开项目或解决方案,并选择工具 > NuGet 包管理器 > 包管理器控制台打开包管理器控制台窗口。执行以下命令安装 :

    Install-Package YunApiSDK
  • 直接下载dll (YunApiSDK.dll),在项目中添加引用。

3. 调用说明

SDK接入调用有两种方式:

  • 通过服务注入的方式接入调用

    特点:接入相对复杂(参考demo的接入处理),但是对高并发的性能处理更好。

    操作步骤:

    1. 配置文件中添加YunApiInfo节点。
      {
        "YunApiInfo": {
          "PartnerID": "2xxxx", // 门户网站中的企业ID
          "SecretKey": "6xxxxxxx", // 门户网站中的密钥
          "ApiServer": "https://api.3dopen.cn" // 门户网站中的接口地址
        }
      }
    2. 注册服务。
      // 注册YunApiClient, 里面会自动注册依赖的httpClient, 所以无需单独再注册httpClient
      services.AddYunApiClient(config.GetSection("YunApiInfo"));
    3. 注入YunApiClient 。
      // 使用IServiceProvider手动解析
      var yunapiClient = sp.GetService<YunApiClient>();
      // 使用依赖注入自动注入
      public class ServiceTest
      {
          private readonly YunApiClient yunapiClient;
          public ServiceTest(YunApiClient yunapiClient)
          {
              this.yunapiClient = yunapiClient;
          }
      }
  • 直接调用SDK对象方法接入

    特点:接入比较简单,使用灵活,测试接入时可以使用该方式。

    操作步骤:

    1. 直接初始化YunApiClient对象
      // 参数分别为门户网站中 开发接口-接口信息 中的企业ID、密钥、接口地址
      var yunapiClient = new YunApiClient(Constants.PARTNERID, Constants.PARTNETKEY, Constants.SERVERADDRESS);

4. 业务快速接入

4.1 获取MinIO临时上传URL

获取MinIO临时授权接口信息:

var tempUrlRes = await yunapiClient.GetPresignedUploadUrlAsync(new GetPresignedUrlRequest { FileName = fileName });

返回数据示例:

{
    "status": {
        "code": 1,
        "msg": "成功"
    },
    "data": {
        "inputNdsFile": "202305101737093718/box.par",
        "url": "http://xxx/202305101737093718/box.par?X-Amz-Algorithm..."
    }
}

4.2 上传文件至MinIO

后端SDK上传MinIO :

// 使用minio临时授权URL上传文件
var uploadUrl= tempUrlRes.Data.Url;
var uploadRes = await yunapiClient.UploadFileByNdsFileUrlAsync(uploadUrl, filePath);

前端网页上传MinIO,上传 URL 为MinIO临时上传路径 tempUrlRes.Data.Url :

//前端页面上传处理
let file = $('#fileSelect')[0].files[0];//选择文件
     $.ajax({
       url: url,   //url是接口返回的临时授权路径
       type: "put",
       data: file, 
       async: true,
       processData: false,
       contentType: false,
       error: function (xhr, status, error) {                   

       },
       success: function (result) {

       },
     });

4.3 插入任务

// 插入任务 其中callbackUrl为回调地址,如果不需要则可以不传或传空
var inputFile = tempUrlRes.Data.InputNdsFile;
var insertRes = await yunapiClient.InsertTaskAsync(new InsertTaskRequest { InputNdsFile = inputFile, ReturnURL = callbackUrl });

4.4 查询任务

// 查询接口
var queryRes = await yunapiClient.QueryTaskAsync(new QueryTaskRequest { TaskID = taskID });

返回数据示例,其中路径地址都使用base64加密处理:

{
    "status": {
        "code": 1,
        "msg": "成功"
    },
    "data": {
        "status": 2,
        "errorDescription": "OK",
        "errorDetail": "OK",
        "outputFiles": "145bf249-98e1-4a7e-8ba2-11a85800a82f.zip",
        "outFilePathType": 0,
        "outputNdsFiles": "aHR0cDovLzEwLjEyMi44Mi45Mjo5MDAwL3l1bmFwaS9lbnRlcnByaXNlLzgxMzg2MzgzMzI2MDQ1MjgxNjkzL2Rvd25sb2FkLzRmM2Q4MjZkLTIwMTQtNDRmMi1iMmU2LTZiOWVmOTBmZWQzMi56aXA/WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1USURCRUQwRTBZMTBENjA5OVYxSSUyRjIwMjQwMTE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDExNlQwMjEyNDNaJlgtQW16LUV4cGlyZXM9MTcyODAwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZYLUFtei1TaWduYXR1cmU9YzVkNGYyZmIyMDQzNjRiMzU5MTczYzEwNTc2YTEwMzA1YjExYTNhZWEwYTQzNWUxYmY0OWVjYTg1OWI2YTgwNA=="
        "errorType": 1,
        "previewURL": "aHR0cHM6Ly9hcGkuM2RvcGVuLmNuL3ByZXZpZXcuaHRtbD9pdGVtQ29kZT02OEMwQTM3MUFFOTk3NUNGNkEzMTUyQzNERTczQzlGQw==",
        "jsonURL": "aHR0cHM6Ly9taW5pby4zZG9wZW4uY24vM2RvcGVuL3RlbXBGaWxlL01vZGVsRmlsZS9OZXdkaW1jaGluYS8xNjgzNzEzOTQ2NjI3LzAvcHJvZHVjdERhdGEuanNvbg==",
        "imgURL": "aHR0cHM6Ly9taW5pby4zZG9wZW4uY24vM2RvcGVuL3RlbXBGaWxlL01vZGVsRmlsZS9OZXdkaW1jaGluYS8xNjgzNzEzOTQ2NjI3L1RodW1ibmFpbC5wbmc="
    }
}

4.5 预览轻量化模型

将字段 previewURL(通过base64编码)解密后,获得轻量化模型预览地址。也可在门户网站,将轻量化模型文件下载到本地磁盘。集成Viewer组件后,通过浏览器预览。

4.6 demo示例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YunApiSDK;
using YunApiSDK.Model.Request;

namespace YunApiSDKDemo
{
    public class YunApiTest
    {
        /// <summary>
        /// 基础流程
        /// </summary>
        /// <param name="yunapiClient"></param>
        /// <param name="callbackUrl"></param>
        /// <returns></returns>
        public async Task Test()
        {
			string partnerID = "xx";企业ID
			string secretKey = "xx";密钥
			string apiServer = "https://api.3dopen.cn";接口地址
			// 参数分别为门户网站中 开发接口-接口信息 中的企业ID、密钥、接口地址
			var yunapiClient = new YunApiClient(partnerID, secretKey, apiServer);
            var filePath = "F:\\model.zip";
            var fileInfo = new FileInfo(filePath);

            // 获取minio临时上传URL
            var tempUrlRes = await yunapiClient.GetPresignedUploadUrlAsync(new GetPresignedUrlRequest { FileName = fileInfo.Name });

            if (tempUrlRes.Status.Code != 1)
            {
                await Console.Out.WriteLineAsync(tempUrlRes.Status.Msg);
                return;
            }

            // 使用minio临时授权URL上传文件
            var uploadRes = await yunapiClient.UploadFileByNdsFileUrlAsync(tempUrlRes.Data.Url, filePath);

            // 回调接口地址,如果需要回调则配置,不需要则不配置,地址为实际业务中开发的回调接口地址,本例为YunApiSDKCallbackDemo中的测试接口
            // 插入任务
            var insertRes = await yunapiClient.InsertTaskAsync(new InsertTaskRequest { InputNdsFile = tempUrlRes.Data.InputNdsFile, ReturnURL = "" });

            if (insertRes.Status.Code != 1)
            {
                await Console.Out.WriteLineAsync(insertRes.Status.Msg);
                return;
            }

            var taskState = 0;
            var outputDataUrl = string.Empty;
            // 此处使用while循环是为了得到轻量化文件下载地址,演示下载文件,实际情况可根据业务调整
            while (taskState < 2)
            {
                // 查询接口
                var queryRes = await yunapiClient.QueryTaskAsync(new QueryTaskRequest { TaskID = insertRes.Data.TaskID });
                if (queryRes?.Status?.Code != 1)
                {
                    break;
                }
                taskState = queryRes.Data?.Status ?? 5;
                outputDataUrl = queryRes.Data?.OutputNdsFiles;
            }

            // 此段是演示下载轻量化文件,可根据实际情况自行调整
            if (taskState == 2 && !string.IsNullOrEmpty(outputDataUrl))
            {
                var decodeUrl = Encoding.UTF8.GetString(Convert.FromBase64String(outputDataUrl));
                
                // 此处是获取url中的文件名,可根据自己实际业务情况,确定要保存的文件名
                Uri uri = new Uri(decodeUrl);
                string fileName = System.IO.Path.GetFileName(uri.LocalPath);

                // 简单使用,演示功能,最佳实践使用IHttpClientFactory.CreateClient()创建
                var httpClient = new HttpClient();
                using (HttpResponseMessage response = await httpClient.GetAsync(decodeUrl))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        using (var fileStream = await response.Content.ReadAsStreamAsync())
                        using (var outputFileStream = System.IO.File.Create(fileName))
                        {
                            await fileStream.CopyToAsync(outputFileStream);
                        }
                        Console.WriteLine("文件下载成功!");
                    }
                    else
                    {
                        Console.WriteLine("请求失败: " + response.ReasonPhrase);
                    }
                }
            }

            // 取消任务
            var removeRes = await yunapiClient.RemoveTaskAsync(new RemoveTaskRequest { TaskList = insertRes.Data.TaskID.ToString() });

        }
    }
}