基于C# Add-in实现从API向Revit导入数据的技术咨询
Revit C# Add-in 导入Web API数据方案
1. 建立与Web API的连接
在Revit插件中调用Web API需要注意Revit主线程限制:所有涉及Revit API的操作必须在主线程执行,但HTTP请求可以放在后台线程完成,避免阻塞Revit界面。以下是基于HttpClient的同步请求示例(若需异步,需确保后续元素操作切回主线程):
代码示例:获取API数据
首先需引用System.Net.Http和Newtonsoft.Json(可通过NuGet安装,打包插件时需包含该dll):
using System.Net.Http; using Newtonsoft.Json; using Autodesk.Revit.UI; // 定义与API返回结构匹配的模型类 public class ApiRoomData { public string RoomName { get; set; } public double Area { get; set; } // 假设单位为平方米 public string LevelName { get; set; } } public static List<ApiRoomData> FetchApiData(string apiUrl) { using (var client = new HttpClient()) { try { // 发送GET请求,同步获取响应(规避异步线程冲突) var response = client.GetAsync(apiUrl).Result; response.EnsureSuccessStatusCode(); // 反序列化JSON数据到模型类 var jsonString = response.Content.ReadAsStringAsync().Result; return JsonConvert.DeserializeObject<List<ApiRoomData>>(jsonString); } catch (HttpRequestException ex) { TaskDialog.Show("API请求错误", ex.Message); return null; } } }
如果API需要身份验证(比如Bearer Token),可添加请求头:
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "your_token_here");
2. 将API数据映射到Revit元素/参数
拿到API数据后,所有修改Revit元素的操作必须在**事务(Transaction)**中执行,同时要处理数据类型转换(比如API的公制单位转Revit内部单位)。
代码示例:创建Revit房间并映射参数
using Autodesk.Revit.DB; public void MapApiDataToRevit(UIApplication uiApp, List<ApiRoomData> apiRooms) { var doc = uiApp.ActiveUIDocument.Document; // 开启事务执行修改 using (var trans = new Transaction(doc, "导入API房间数据")) { trans.Start(); foreach (var roomData in apiRooms) { // 1. 查找对应标高 var level = new FilteredElementCollector(doc) .OfClass(typeof(Level)) .Cast<Level>() .FirstOrDefault(l => l.Name.Equals(roomData.LevelName, StringComparison.OrdinalIgnoreCase)); if (level == null) { TaskDialog.Show("警告", $"未找到标高:{roomData.LevelName}"); continue; } // 2. 创建房间边界(示例为简单矩形,实际需替换为API返回的边界坐标) var boundaryLoop = new CurveLoop(); boundaryLoop.Append(Line.CreateBound(new XYZ(0, 0, level.Elevation), new XYZ(10, 0, level.Elevation))); boundaryLoop.Append(Line.CreateBound(new XYZ(10, 0, level.Elevation), new XYZ(10, 10, level.Elevation))); boundaryLoop.Append(Line.CreateBound(new XYZ(10, 10, level.Elevation), new XYZ(0, 10, level.Elevation))); boundaryLoop.Append(Line.CreateBound(new XYZ(0, 10, level.Elevation), new XYZ(0, 0, level.Elevation))); // 3. 创建房间 var room = doc.Create.NewRoom(level, new List<CurveLoop> { boundaryLoop }); // 4. 映射系统参数:设置房间名称 room.get_Parameter(BuiltInParameter.ROOM_NAME).Set(roomData.RoomName); // 5. 转换面积单位(API返回平方米转Revit内部英尺单位) double areaInSquareFeet = UnitUtils.ConvertToInternalUnits(roomData.Area, DisplayUnitType.DUT_SQUARE_METERS); room.get_Parameter(BuiltInParameter.ROOM_AREA).Set(areaInSquareFeet); } trans.Commit(); TaskDialog.Show("完成", "API数据导入成功"); } }
关键注意事项
- 自定义参数映射:若需设置共享参数,可通过参数名称或GUID查找:
var customParam = room.LookupParameter("自定义房间编号"); if (customParam != null && !customParam.IsReadOnly) { customParam.Set(roomData.RoomId); } - 异步请求的线程处理:如果用异步HTTP请求,需切回Revit主线程执行元素操作:
Task.Run(async () => { var client = new HttpClient(); var data = await client.GetFromJsonAsync<List<ApiRoomData>>(apiUrl); uiApp.Dispatcher.Invoke(() => MapApiDataToRevit(uiApp, data)); }); - 数据校验:导入前需校验API数据的合法性(比如标高是否存在、参数值是否符合Revit要求),避免事务回滚。
参考资源
- Revit API官方文档:重点掌握
Transaction、Element、Parameter、FilteredElementCollector类的用法 - .NET官方文档:
HttpClient的请求配置与异常处理 - Newtonsoft.Json文档:JSON序列化与反序列化的进阶配置
内容的提问来源于stack exchange,提问作者Vasundhara
相关产品推荐
相关产品推荐

