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

.NET9中如何将JsonDocument转换为RulesEngine可处理的格式以解决路径查找失败问题

.NET9中如何将JsonDocument转换为RulesEngine可处理的格式以解决路径查找失败问题

嘿,我刚好碰到过类似的情况,咱们来一步步解决这个问题!

问题根源

你遇到的路径找不到错误,核心原因是:RulesEngine需要的是普通的CLR对象(比如匿名类型、强类型POCO或者ExpandoObject),而你之前的两种尝试都没生成这种对象:

  • 直接用data.RootElement.GetRawText()得到的是JSON字符串,不是可解析的对象;
  • 直接调用JsonSerializer.Deserialize不指定类型时,System.Text.Json会把JSON对象反序列化为JsonElement(而不是匿名对象),RulesEngine解析时会识别到它的内部属性(比如ValueKind),导致路径匹配失败。

而你手动创建的匿名对象new { external = new { terminal = "1234" } }能正常工作,正是因为它是标准的CLR对象,RulesEngine可以直接遍历它的属性。

解决方案

根据你的场景,这里有三种可行的方法,你可以按需选择:

1. 反序列化为匿名类型(适合结构固定的场景)

既然手动创建的匿名对象有效,我们可以用匿名类型作为模板,把JsonDocument反序列化成对应的匿名对象:

private static async ValueTask<List<RuleResultTree>> MapAndExecute(JsonDocument data, RulesEngine.RulesEngine rulesEngine, string workflowName) {
    // 定义和你的JSON结构完全匹配的匿名类型模板
    var template = new {
        External = new {
            Terminal = "",
            Previous = 0,
            Now = 0,
            StringCollection = new List<string>()
        }
    };
    
    // 反序列化RootElement到匿名类型,可选开启大小写不敏感匹配
    var parsedData = JsonSerializer.Deserialize(
        data.RootElement, 
        template.GetType(), 
        new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
    );
    
    return await rulesEngine.ExecuteAllRulesAsync(workflowName, new RuleParameter("ruleData", parsedData));
}

这样反序列化出来的对象和你手动创建的匿名对象结构完全一致,RulesEngine就能正确解析ruleData.External.Terminal这类路径了。

2. 反序列化为ExpandoObject(适合动态结构的场景)

如果你的JSON结构不固定,用ExpandoObject会更灵活,它是.NET原生的动态类型,RulesEngine可以正常解析它的属性:

private static async ValueTask<List<RuleResultTree>> MapAndExecute(JsonDocument data, RulesEngine.RulesEngine rulesEngine, string workflowName) {
    var parsedData = JsonSerializer.Deserialize<ExpandoObject>(
        data.RootElement, 
        new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
    );
    
    return await rulesEngine.ExecuteAllRulesAsync(workflowName, new RuleParameter("ruleData", parsedData));
}

这种方法不需要提前知道JSON结构,适合处理动态输入的场景。

3. 创建强类型POCO类(推荐用于结构固定的生产环境)

如果你的JSON结构是固定的,最推荐的方式是创建对应的强类型类,这样既有编译时类型检查,性能也更好:

// 先定义匹配JSON结构的POCO类
public class ExternalInfo {
    public string Terminal { get; set; }
    public int Previous { get; set; }
    public int Now { get; set; }
    public List<string> StringCollection { get; set; }
}

public class RuleInput {
    public ExternalInfo External { get; set; }
}

// 修改你的方法
private static async ValueTask<List<RuleResultTree>> MapAndExecute(JsonDocument data, RulesEngine.RulesEngine rulesEngine, string workflowName) {
    var parsedData = JsonSerializer.Deserialize<RuleInput>(
        data.RootElement, 
        new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
    );
    
    return await rulesEngine.ExecuteAllRulesAsync(workflowName, new RuleParameter("ruleData", parsedData));
}

强类型的好处是能避免拼写错误,而且调试和维护起来更方便。

注意事项

如果你的规则里用的是小写路径(比如ruleData.external.terminal),记得在反序列化时开启PropertyNameCaseInsensitive = true,这样JSON里的External会和规则里的external正确匹配。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:38:01