Revit Design Automation工作项JSON反序列化报错排查
报错根因
两次报错由三个核心问题共同导致:
- 前端JSON文件生成逻辑错误:直接将未序列化的JavaScript对象
data传入File构造函数时,运行环境会自动对普通对象执行toString()转换,最终写入文件的内容是字符串[object Object],完全不是合法JSON格式。第二次报错提示Unexpected character encountered while parsing value: o. Path '', line 1, position 1,就是因为读取到的文件内容第2位(索引从0开始)是字符o,和[object Object]的内容完全吻合。 - C#数据模型与JSON结构不匹配:你构造的参数中
ElementIds是包含UniqueId属性的对象数组,但初始C#代码将ElementIds定义为string[]字符串数组,序列化器无法将对象结构直接转换为字符串,因此抛出“需要JSON对象、实际读到JSON数组”的类型不兼容异常。 - 修改后的C#代码存在两处错误:一是读取的文件名为
cache.json,和实际上传的参数文件名inputParameters.json不匹配;二是错误将根结构反序列化为List<InputCache>,但你的参数根结构是单个JSON对象,并非数组。
正确实现方案
分别修复前端文件生成逻辑和C#端反序列化逻辑即可解决问题。
1. 修复前端JSON生成代码
必须先通过JSON.stringify将JS对象序列化为合法JSON字符串,再传入File构造函数,修正后代码:
const data = { ModelId: "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjNSTzhMWmtUVGVHM3p1M1FoNjRGM3c_dmVyc2lvbj0x", ElementIds: [ { "UniqueId": "ca5762b5-0f46-4a2f-8599-1d1a5dd19a81-00024b8c" }, { "UniqueId": "91e18c07-1bae-4949-a093-e0a4552bb478-000241ea" } ] }; // 关键:先序列化为JSON字符串再生成文件 var file = new File([JSON.stringify(data)], "inputParameters.json", { type: "application/json" });
2. 修复C#端反序列化代码
对齐JSON结构定义数据模型,读取正确的文件名,修正后代码:
public static bool ImportFromCache(Application rvtApp, Document doc) { InputCache inputCache = InputCache.Parse("inputParameters.json"); // 后续业务逻辑 return true; } // 匹配ElementIds数组项的结构 internal class ElementIdEntry { public string UniqueId { get; set; } = ""; } internal class InputCache { public string ModelId { get; set; } = ""; // 类型与JSON结构对齐,改为对象数组 public ElementIdEntry[] ElementIds { get; set; } = Array.Empty<ElementIdEntry>(); static public InputCache Parse(string jsonPath) { if (!File.Exists(jsonPath)) { return new InputCache { ModelId = "", ElementIds = Array.Empty<ElementIdEntry>() }; } string jsonContents = File.ReadAllText(jsonPath); return JsonConvert.DeserializeObject<InputCache>(jsonContents); } }
简化方案:如果业务逻辑只需要
ElementIds中的UniqueId值,不需要额外定义子项类,可以直接修改前端参数结构,把ElementIds改为纯字符串数组:ElementIds: [ "ca5762b5-0f46-4a2f-8599-1d1a5dd19a81-00024b8c", "91e18c07-1bae-4949-a093-e0a4552bb478-000241ea" ]这种情况下C#端可以直接保留
public string[] ElementIds { get; set; }的定义,无需额外创建ElementIdEntry类。
内容的提问来源于stack exchange,提问作者bim2016
相关产品推荐
相关产品推荐

