
在我的博客《C#二次开发BIMFACE系列61 File Management文件管理服务接口二次开发及实战详解》最后列出了 File Management 的接口,本篇主要介绍对该接口的封装及Demo程序。
本篇内容对应的视频教程《BIMFACE二次开发系列11.2 File Management接口二次开发及实战详解》
B站:https://www.bilibili.com/video/BV1Ei4y1U7k7
头条:https://www.ixigua.com/7087537345448116776
文件管理File Management API由以下基本类型构成,熟悉以下名词,以便更好的理解 File Management 模块

以上几种存储类型之间存在关联关系,层级关系如下所示:
Access Token代表了用户当前应用的身份,用户可以通过Access Token对自己应用内的文件发起文件上传、下载、删除、更新等操作,同时也能访问所有BIMFACE的服务端数据接口进行轻量化和数据服务等操作。因此,获取AccessToken是程序开发的第一步,更多关于Access Token的说明可参考Access Token
当用户访问File Management API出现错误时,File Management将返回给用户一个HTTP状态码,错误原因将在响应正文中返回,便于用户定位问题。
以下是伴随HTTP 404的错误码响应示例。
{ "timestamp": 1646985853402, "status": 404, "error": "Not Found", "message": "", "path": "/bdfs/v1/projects/10000000006016/folders/10000000006017/parent"}

在我的开源项目《BIMFACE.SDK.CSharp》中封装了54个File Management 接口的同步与异步方法,如下图

这里列出几个核心接口的封装代码
获取Hub列表


1 /// <summary> 2 /// 获取Hub列表 3 /// <para>通过该接口可查询您的账号已注册哪些存储中心(Hub),您可以将文件上传到已注册的存储空间里。</para> 4 /// </summary> 5 /// <param name="accessToken">【必填】令牌</param> 6 /// <param name="dateTimeFrom">【选填】开始时间,筛选时间范围内创建的Hub,格式为:yyyy-MM-dd HH:mm:ss</param> 7 /// <param name="dateTimeTo">【选填】终止时间,筛选时间范围内创建的Hub,格式为:yyyy-MM-dd HH:mm:ss</param> 8 /// <param name="info">【选填】描述信息</param> 9 /// <param name="name">【选填】Hub名称</param>10 /// <param name="tenantCode">【选填】产品所属的租户 (默认值:"BIMFACE")</param>11 /// <returns></returns>12 /// <exception cref="BIMFaceException"></exception>13 public virtual HubsResponse GetHubs(string accessToken, string dateTimeFrom = "", string dateTimeTo = "", string info = "", string name = "", string tenantCode = "BIMFACE")14 {15 /*官方文档:https://bimface.com/docs/file-management/v1/api-reference/getHubListUsingGET.html */16 17 //GET https://api.bimface.com/bdfs/domain/v1/hubs18 string url = BIMFaceConstants.API_HOST + "/bdfs/domain/v1/hubs?1=1";19 if (!string.IsNullOrWhiteSpace(dateTimeFrom))20 {21 url += "&dateTimeFrom=" + dateTimeFrom;22 }23 if (!string.IsNullOrWhiteSpace(dateTimeTo))24 {25 url += "&dateTimeTo=" + dateTimeTo;26 }27 if (!string.IsNullOrWhiteSpace(info))28 {29 url += "&info=" + info;30 }31 if (!string.IsNullOrWhiteSpace(name))32 {33 url += "&name=" + name;34 }35 if (!string.IsNullOrWhiteSpace(tenantCode))36 {37 url += "&tenantCode=" + tenantCode;38 }39 40 BIMFaceHttpHeaders headers = new BIMFaceHttpHeaders();41 headers.AddOAuth2Header(accessToken);42 43 try44 {45 HubsResponse response;46 47 HttpManager httpManager = new HttpManager(headers);48 HttpResult httpResult = httpManager.Get(url);49 if (httpResult.Status == HttpResult.STATUS_SUCCESS)50 {51 response = httpResult.Text.DeserializeJsonToObject<HubsResponse>();52 }53 else54 {55 response = new HubsResponse56 {57 Message = httpResult.RefText58 };59 }60 61 return response;62 }63 catch (Exception ex)64 {65 throw new BIMFaceException("[获取Hubs]发生异常!", ex);66 }67 }
创建项目


1 /// <summary> 2 /// 创建项目 3 /// <para>用Access Token创建项目,对文件分项目进行管理,创建项目之前需要获取应用所属的hubId。</para> 4 /// </summary> 5 /// <param name="accessToken">【必填】令牌</param> 6 /// <param name="hubId">【必填】hub编号</param> 7 /// <param name="projectName">【必填】项目名称</param> 8 /// <param name="projectInfo">【选填】项目描述,最多255个字符</param> 9 /// <param name="projectThumbnail">【选填】项目缩略图url</param>10 /// <returns></returns>11 /// <exception cref="BIMFaceException"></exception>12 public virtual ProjectResponse CreateProject(string accessToken, string hubId, string projectName, string projectInfo = null, string projectThumbnail = null)13 {14 /*官方文档:https://bimface.com/docs/file-management/v1/api-reference/createProjectUsingPOST.html */15 16 //POST https://api.bimface.com/bdfs/domain/v1/hubs/{hubId}/projects17 string url = string.Format(BIMFaceConstants.API_HOST + "/bdfs/domain/v1/hubs/{0}/projects", hubId);18 19 string data = new ProjectSaveRequest20 {21 Name = projectName,22 Thumbnail = projectThumbnail,23 Info = projectInfo24 }.SerializeToJson();25 26 BIMFaceHttpHeaders headers = new BIMFaceHttpHeaders();27 headers.AddOAuth2Header(accessToken);28 29 try30 {31 ProjectResponse response;32 33 HttpManager httpManager = new HttpManager(headers);34 HttpResult httpResult = httpManager.Post(url, data);35 if (httpResult.Status == HttpResult.STATUS_SUCCESS)36 {37 response = httpResult.Text.DeserializeJsonToObject<ProjectResponse>();38 }39 else40 {41 response = new ProjectResponse42 {43 Message = httpResult.RefText44 };45 }46 47 return response;48 }49 catch (Exception ex)50 {51 throw new BIMFaceException("[创建项目信息]发生异常!", ex);52 }53 }
指定目录下创建文件夹


1 /// <summary> 2 /// 指定目录下创建文件夹 3 /// <para>在指定的位置创建文件夹,可对文件进行分类管理。需要获取所属的项目Id,以及文件夹所在位置的上层文件Id或文件路径,两个参数必须二选一填入。</para> 4 /// </summary> 5 /// <param name="accessToken">【必填】令牌</param> 6 /// <param name="projectId">【必填】</param> 7 /// <param name="folderName">【必填】 文件夹名称</param> 8 /// <param name="parentPath">【必填】父目录文件路径,parentId和parentPath,必须二选一填入</param> 9 /// <param name="parentId">【必填】父目录文件ID,parentId和parentPath,必须二选一填入</param>10 /// <param name="autoRename">【选填】当存在同名文件夹时,是否重命名(默认false,false情况下有同名文件夹则报错)</param>11 /// <returns></returns>12 /// <exception cref="BIMFaceException"></exception>13 public virtual FolderResponse CreateFolder(string accessToken, string projectId, string folderName, string parentPath, string parentId, bool? autoRename = null)14 {15 /* 官方文档:https://bimface.com/docs/file-management/v1/api-reference/createFolderUsingPOST.html */16 17 //POST https://api.bimface.com/bdfs/data/v1/projects/{projectId}/folders18 string url = string.Format(BIMFaceConstants.API_HOST + "/bdfs/data/v1/projects/{0}/folders", projectId);19 string data = new FolderCreateRequest20 {21 Name = folderName,22 ParentPath = parentPath,23 ParentId = parentId,24 AutoRename = autoRename25 }.SerializeToJson();26 27 BIMFaceHttpHeaders headers = new BIMFaceHttpHeaders();28 headers.AddOAuth2Header(accessToken);29 30 try31 {32 FolderResponse response;33 34 HttpManager httpManager = new HttpManager(headers);35 HttpResult httpResult = httpManager.Post(url,data);36 if (httpResult.Status == HttpResult.STATUS_SUCCESS)37 {38 response = httpResult.Text.DeserializeJsonToObject<FolderResponse>();39 }40 else41 {42 response = new FolderResponse43 {44 Message = httpResult.RefText45 };46 }47 48 return response;49 }50 catch (Exception ex)51 {52 throw new BIMFaceException("[创建文件夹信息]发生异常!", ex);53 }54 }
上传文件(普通文件流方式)


1 /// <summary> 2 /// 普通文件流上传文件【使用BIMFACE公有云时不推荐使用该方式。推荐使用文件直传 UploadFileByPolicy()方法,效率更高】。 3 /// <para>使用普通文件流上传,文件流需要在request body中传递。</para> 4 /// </summary> 5 /// <param name="accessToken">【必填】令牌</param> 6 /// <param name="projectId">【必填】项目ID</param> 7 /// <param name="fileName">【必填】文件的名称(不包含路径)</param> 8 /// <param name="fileStream">【必填】文件流</param> 9 /// <param name="parentId">【必填】父文件夹Id,parentId和parentPath必须二选一填入</param>10 /// <param name="parentPath">【必填】父文件夹路径,parentId和parentPath必须二选一填入</param>11 /// <param name="autoRename">【可选】当存在同名文件时,是否自动重命名,默认为false </param>12 /// <param name="sourceId">【可选】调用方的文件源ID,不能重复</param>13 /// <returns></returns>14 public virtual FileUpload2Response UploadFileByStream(string accessToken, string projectId, string fileName, Stream fileStream, string parentId, string parentPath, bool? autoRename = null, string sourceId = "")15 {16 /* 官方文档:https://bimface.com/docs/file-management/v1/api-reference/uploadFileItemUsingPOST.html */17 18 /* 此API详解,参考作者博客:《C#开发BIMFACE系列4 服务端API之源上传文件》 https://www.cnblogs.com/SavionZhang/p/11425804.html */19 20 /* 重要提示:使用普通文件流上传,不支持表单方式; 文件流需要在 request body 中传递 */21 22 byte[] fileBytes = fileStream.ToByteArray();23 24 //POST https://api.bimface.com/bdfs/data/v1/projects/{projectId}/fileItems25 string url = string.Format(BIMFaceConstants.API_HOST + "/bdfs/data/v1/projects/{0}/fileItems", projectId);26 url = url + "?name=" + fileName.UrlEncode(Encoding.UTF8); // 使用URL编码(UTF-8)27 if (!string.IsNullOrEmpty(parentId))28 {29 url = url + "&parentId=" + parentId;30 }31 if (!string.IsNullOrEmpty(parentPath))32 {33 url = url + "&parentPath=" + parentPath;34 }35 36 url = url + "&length=" + fileBytes.Length;37 38 if (autoRename.HasValue)39 {40 url = url + "&autoRename=" + autoRename.Value;41 }42 if (!string.IsNullOrEmpty(sourceId))43 {44 url = url + "&sourceId=" + sourceId;45 }46 47 BIMFaceHttpHeaders headers = new BIMFaceHttpHeaders();48 headers.AddOAuth2Header(accessToken);49 50 try51 {52 FileUpload2Response response;53 54 HttpManager httpManager = new HttpManager(headers);55 HttpResult httpResult = httpManager.UploadData(url, fileBytes, WebRequestMethods.Http.Post);56 if (httpResult.Status == HttpResult.STATUS_SUCCESS)57 {58 response = httpResult.Text.DeserializeJsonToObject<FileUpload2Response>();59 }60 else61 {62 response = new FileUpload2Response63 {64 Message = httpResult.RefText65 };66 }67 68 return response;69 }70 catch (Exception ex)71 {72 throw new BIMFaceException("[普通文件流上传文件]发生异常!", ex);73 }74 }
上传文件(外部文件url方式)


1 /// <summary> 2 /// 指定外部文件url方式上传文件。 3 /// <para>如果需要上传的文件不在本地,且该文件可以通过指定的HTTP URL可以下载,BIMFACE支持直接传一个外部的HTTP文件URL,BIMFACE会去下载该文件,而无须用户先下载再上传。</para> 4 /// </summary> 5 /// <param name="accessToken">【必填】令牌</param> 6 /// <param name="projectId">【必填】项目ID</param> 7 /// <param name="fileName">【必填】文件的名称(不包含路径)</param> 8 /// <param name="parentId">【必填】父文件夹Id,parentId和parentPath必须二选一填入</param> 9 /// <param name="parentPath">【必填】父文件夹路径,parentId和parentPath必须二选一填入</param>10 /// <param name="fileUrl">【必填】外部文件的url地址</param>11 /// <param name="autoRename">【可选】当存在同名文件时,是否自动重命名,默认为false </param>12 /// <param name="sourceId">【可选】调用方的文件源ID,不能重复</param>13 /// <param name="etag">【可选】文件etag</param>14 /// <param name="maxLength">【可选】</param>15 /// <returns></returns>16 public virtual FileUpload2Response UploadFileByUrl(string accessToken, string projectId, string fileName, string parentId, string parentPath, string fileUrl, bool? autoRename = null, string sourceId = "", string etag = "", long? maxLength = null)17 {18 /* 官方文档:https://bimface.com/docs/file-management/v1/api-reference/uploadByUrlUsingPOST.html */19 20 /* 此API详解,参考作者博客:《C#开发BIMFACE系列4 服务端API之源上传文件》 https://www.cnblogs.com/SavionZhang/p/11425804.html */21 22 /* 如果需要上传的文件不在本地,且该文件可以通过指定的HTTP URL可以下载,BIMFACE支持直接传一个外部的HTTP文件URL, BIMFACE会去下载该文件,而无须用户先下载,再上传。 */23 24 //POST https://api.bimface.com/bdfs/data/v1/projects/{projectId}/fileItems/sourceUrl25 string url = string.Format(BIMFaceConstants.API_HOST + "/bdfs/data/v1/projects/{0}/fileItems/sourceUrl", projectId);26 url = url + "?name=" + fileName.UrlEncode(Encoding.UTF8); // 使用URL编码(UTF-8)27 28 if (!string.IsNullOrWhiteSpace(parentId))29 {30 url = url + "&parentId=" + parentId;31 }32 if (!string.IsNullOrWhiteSpace(parentPath))33 {34 url = url + "&parentPath=" + parentPath;35 }36 37 url = url + "&url=" + fileUrl.UriEscapeDataString();38 39 if (autoRename.HasValue)40 {41 url = url + "&autoRename=" + autoRename.Value;42 }43 if (!string.IsNullOrWhiteSpace(etag))44 {45 url = url + "&etag=" + etag;46 }47 if (maxLength.HasValue)48 {49 url = url + "&maxLength=" + maxLength.Value;50 }51 if (!string.IsNullOrWhiteSpace(sourceId))52 {53 url = url + "&sourceId=" + sourceId;54 }55 56 BIMFaceHttpHeaders headers = new BIMFaceHttpHeaders();57 headers.AddOAuth2Header(accessToken);58 59 try60 {61 FileUpload2Response response;62 63 HttpManager httpManager = new HttpManager(headers);64 HttpResult httpResult = httpManager.Post(url);65 if (httpResult.Status == HttpResult.STATUS_SUCCESS)66 {67 response = httpResult.Text.DeserializeJsonToObject<FileUpload2Response>();68 }69 else70 {71 response = new FileUpload2Response72 {73 Message = httpResult.RefText74 };75 }76 77 return response;78 }79 catch (Exception ex)80 {81 throw new BIMFaceException("[指定外部文件url方式上传文件]发生异常!", ex);82 }83 }
上传文件(文件直传)


1 /// <summary> 2 /// 【推荐使用该方式】根据policy凭证在web端上传文件。 3 /// <para>通过接口获取文件直传的policy凭证后,可以直接在前端使用表单上传方式将文件上传到BIMFACE的对象存储上。</para> 4 /// <para>特别提醒:BIMFACE公有云支持文件直传。私有化部署时使用的对象存储是 MinIO,不支持 Policy 上传。使用普通文件流上传 或者 指定外部文件URL方式上传。</para> 5 /// </summary> 6 /// <param name="accessToken">【必填】令牌</param> 7 /// <param name="projectId">【必填】项目ID</param> 8 /// <param name="fileFullName">【必填】待上传的文件(包含全路径的完全限定名)</param> 9 /// <param name="parentId">【必填】父文件夹Id,parentId和parentPath必须二选一填入</param>10 /// <param name="parentPath">【必填】父文件夹路径,parentId和parentPath必须二选一填入</param>11 /// <param name="autoRename">【可选】当存在同名文件时,是否自动重命名,默认为false </param>12 /// <param name="sourceId">【可选】调用方的文件源ID,不能重复</param>13 /// <param name="maxLength">【可选】</param>14 /// <returns></returns>15 public virtual FileUpload2Response UploadFileByPolicy(string accessToken, string projectId, string fileFullName, string parentId, string parentPath, bool? autoRename = null, string sourceId = "", long? maxLength = null)16 {17 /* 官方文档:https://bimface.com/docs/file-management/v1/api-reference/uploadByPolicyUsingPOST.html */18 /* 此API详解,参考作者博客:《C#开发BIMFACE系列5 服务端API之文件直传》 https://www.cnblogs.com/SavionZhang/p/11425945.html */19 20 /* BIMFACE使用了分布式对象存储来存储用户上传的模型/图纸文件。21 如使用普通的文件上传接口,文件流会通过BIMFACE的服务器,再流向最终的分布式存储系统,整个上传过程会受BIMFACE服务器的带宽限制,上传速度非最优。 22 如使用文件直传接口,开发者应用在申请到一个Policy凭证后,可以直接上传文件跟BIMFACE后台的分布式存储系统, 23 这样上传速度和稳定性都会有提升,是我们推荐的上传方式。 24 */25 26 /* 使用流程如下:27 1、开发者应用向BIMFACE申请上传Policy请求。28 2、BIMFACE返回上传Policy和签名给开发者应用。29 3、开发者应用使用在第二个步骤中获取的URL信息,直接上传文件数据到BIMFACE后端的分布式对象存储。30 */31 32 FileUpload2Response response = null;33 try34 {35 string fileName = new FileInfo(fileFullName).Name;36 37 FileUploadPolicyResponse policyResponse = GetFileUploadPolicy(accessToken, projectId, fileName, parentId, parentPath, autoRename, sourceId, maxLength);38 if (policyResponse.Code == HttpResult.STATUS_SUCCESS)39 {40 /* 官方文档 https://bimface.com/docs/file-management/v1/api-reference/getFilePolicyUsingGET.html41 * 中说明该接口的请求地址为:POST https://api.bimface.com/bdfs/data/v1/projects/policy42 *43 * 经测试44 * (1)使用该地址在postman中测试可以成功。但是使用本程序测试失败,提示 unauthorized。Full authentication is required to access this resource。45 * (2)使用“获取文件直传的policy凭证”接口中返回的 host 地址(https://bf-prod-srcfile.oss-cn-beijing.aliyuncs.com),本程序测试成功。46 */47 48 //string url = BIMFaceConstants.API_HOST + "/bdfs/data/v1/projects/policy";49 string url = policyResponse.Data.Host;50 51 /* C# 语言 Dictionary 字典中 key 是关键字,不能添加进去。所以统一添加了响应的后缀 _BIMFACE_,解析时再去除后缀 */52 NameValueCollection kVDatas = new NameValueCollection();53 kVDatas.Add("name" + StringUtils.Symbol.KEY_SUFFIX, fileName);54 kVDatas.Add("key" + StringUtils.Symbol.KEY_SUFFIX, policyResponse.Data.ObjectKey);55 kVDatas.Add("policy" + StringUtils.Symbol.KEY_SUFFIX, policyResponse.Data.Policy);56 kVDatas.Add("OSSAccessKeyId" + StringUtils.Symbol.KEY_SUFFIX, policyResponse.Data.AccessId);57 kVDatas.Add("success_action_status" + StringUtils.Symbol.KEY_SUFFIX, "200");58 kVDatas.Add("callback" + StringUtils.Symbol.KEY_SUFFIX, policyResponse.Data.CallbackBody);59 kVDatas.Add("signature" + StringUtils.Symbol.KEY_SUFFIX, policyResponse.Data.Signature);60 61 BIMFaceHttpHeaders headers = new BIMFaceHttpHeaders();62 headers.AddOAuth2Header(accessToken);63 64 HttpManager httpManager = new HttpManager(headers);65 HttpResult httpResult = httpManager.UploadFormByMultipart(url, fileFullName, kVDatas);66 if (httpResult.Status == HttpResult.STATUS_SUCCESS)67 {68 response = httpResult.Text.DeserializeJsonToObject<FileUpload2Response>();69 }70 else71 {72 response = new FileUpload2Response73 {74 Message = httpResult.RefText75 };76 }77 }78 79 return response;80 }81 catch (Exception ex)82 {83 throw new BIMFaceException("[通过文件直传的policy凭证,直接上传文件时]发生异常!", ex);84 }85 }
其他接口封装,请下载《BIMFACE.SDK.CSharp》进行阅读。

运行效果如下:






其他接口,请下载《BIMFACE.SDK.CSharp》进行体验。
通过直流上传、表单上传、追加上传的方式上传单个文件,文件的大小不能超过5 GB。
目前支持的文件格式有50+种二维及三维格式,覆盖建筑、化工、机械、能源等行业。
文件上传前,请确认文件名称中不包含特殊字符 / \n * <> | " : ?,否则文件无法上传成功。
默认情况下,如果上传的文件与已有文件同名,无法创建成功并给出错误提示。如果希望创建同名文件,您可以在上传请求的Header中携带参数autoRename,并指定其值为true。
当接口请求参数中同时存在文件Id和文件Path时,请选择其中一个参数填写;若您同时填写,且两个参数指向的文件不同时,Id优先级高于Path。
单个存储空间的容量不限制。
成在管理,败在经验;嬴在选择,输在不学! 贵在坚持!
欢迎关注作者头条号 张传宁IT讲堂,获取更多IT文章、视频等优质内容。
个人作品
1、BIMFace.Community.SDK.NET
开源地址:https://gitee.com/NAlps/BIMFace.SDK
系列博客:https://www.cnblogs.com/SavionZhang/p/11424431.html
系列视频:https://www.cnblogs.com/SavionZhang/p/14258393.html
2、ZCN.NET.Common
开源地址:https://gitee.com/NAlps/zcn.net.common
技术栈
1、Visual Studio、.C#/.NET、.NET Core、MVC、Web API、RESTful API、gRPC、SignalR、Python
2、jQuery、Vue.js、Bootstrap
3、数据库:SQLServer、MySQL、PostgreSQL、Oracle、SQLite、Redis、MongoDB、ElasticSearch、TiDB、达梦DM、人大金仓、 神通、南大通用 GBase
4、ORM:Dapper、Entity Framework、FreeSql、SqlSugar、分库分表、读写分离
5、架构:领域驱动设计 DDD、ABP
6、环境:跨平台、Windows、Linux(CentOS、麒麟、统信UOS、深度Linux)、maxOS、IIS、Nginx
7、移动App:Android、IOS、HarmonyOS、微信、小程序、uni-app、MUI、Xamarin、Smobiler
云原生、微服务、Docker、CI/CD、DevOps、K8S;
Dapr、RabbitMQ、Kafka、分布式、大数据、高并发、负载均衡、中间件、RPC、ELK;
.NET + Docker + jenkins + Github + Harbor + K8S;
出处:www.cnblogs.com/SavionZhang
作者:张传宁 微软MCP、系统架构设计师、系统集成项目管理工程师、科技部创新工程师。
专注于微软.NET技术(.NET Core、Web、MVC、WinForm、WPF)、通用权限管理系统、工作流引擎、自动化项目(代码)生成器、SOA 、DDD、 云原生(Docker、微服务、DevOps、CI/CD);PDF、CAD、BIM 审图等研究与应用。
多次参与电子政务、图书教育、生产制造等企业级大型项目研发与管理工作。
熟悉中小企业软件开发过程:需求分析、架构设计、编码测试、实施部署、项目管理。通过技术与管理帮助中小企业快速化实现互联网技术全流程解决方案。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如有问题,可以通过邮件905442693@qq.com联系。共同交流、互相学习。
如果您觉得文章对您有帮助,请点击文章右下角【推荐】。您的鼓励是作者持续创作的最大动力!