ASP Core 将 JSON 反序列化为派生类

问题描述 投票:0回答:1

我有一个前端应用程序正在生成一个 JSON 对象(我们将其称为 RuleGroup)。每个规则组都包含子组或节点的列表。下面是一个大概的例子

{
    "combinator": "OR",   <---RuleGroup 
    "not": true,
    "criteria": [
        {
            "field": "path", <---RuleCriteria
            "key": "",
            "value": "",
            "operator": "="
        },
        {
            "combinator": "AND", <---RuleGroup 
            "not": false,
            "criteria": [
                {
                    "field": "header", <---Node
                    "key": "",
                    "value": "",
                    "operator": "="
                },
            ]
        }
    ]
}

如何在 API 控制器上反序列化这样的对象? 我已经尝试设置一些像这样的类型,但是我的条件列表最终充满了无法转换为其他两种类型的 BaseRule 对象。

public class RuleGroup : BaseRule
{
    public string Combinator { get; set; }
    public bool Not { get; set; }
    public List<BaseRule> Criteria { get; set; }
}

public class RuleCriteria : BaseRule
{
    public string Field { get; set; }
    public string Operator { get; set; }
    public string Key { get; set; }
    public string Value { get; set; }
}

public class BaseRule
{
}

我怀疑我需要的是类似 https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism?pivots=dotnet-8-0#polymorphic-type-鉴别器但是我真的不想在我的数据中添加专用类型字段。

我的最后一个选择是手动将数据反序列化回适当的对象。

如果有一种方法可以在不使用我自己的解串器的情况下完成此操作,请告诉我 谢谢

c# json asp.net-core .net-core
1个回答
0
投票

我使用 https://json2csharp.com/ 来查看它会根据您的示例生成什么,我收到:

// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class Criterion
{
    public string Field { get; set; }
    public string Key { get; set; }
    public string Value { get; set; }
    public string Operator { get; set; }
    public string Combinator { get; set; }
    public bool? Not { get; set; }
    public List<Criterion> Criteria { get; set; }
}

public class Root
{
    public string Combinator { get; set; }
    public bool Not { get; set; }
    public List<Criterion> Criteria { get; set; }
}

在我看来,这是有道理的。使用此类,您将获得对象。问题是:“如何区分RuleGroup和RuleCriteria”。为了解决这个问题,我将扩展

Criterion
类:

public class Criterion
{
    // all properties

    // conditions that distinguish the "type"
    public bool IsRuleGroup() => !string.IsNullOrEmpty(Combinator);
    public bool IsRuleCriteria() => string.IsNullOrEmpty(Combinator);
}
© www.soinside.com 2019 - 2024. All rights reserved.