我有一个前端应用程序,它正在生成一个SON对象(让我们称之为RuleGroup).每个RuleGroup包含子组或 node 的列表.

以下是一个大致的例子:

{
    "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控制器上对这样的对象进行子化?

我try 过设置一些类似的类型,但我的条件列表最终充满了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-discriminators之类的东西,但我真的不想向我的数据中添加专用的类型字段.

我的最后一个 Select 是手动将数据重新子化回适当的对象中.

如果有一种方法可以在我自己滚动的情况下做到这一点,请告诉我.

谢谢

推荐答案

就我个人而言,我会 Select "标准"的多态方法,为类型RST提供额外属性,IMO它是代码方面最干净的方法,但如果它不可行(例如,SON是由外部系统生成的,您无法控制它)或任何其他原因-推出custom converter是我建议考虑的选项.您可以使用某些标记属性的存在来确定目标类型,简单的类型可以如下所示:

public class RuleConverter : JsonConverter<BaseRule>
{
    public override BaseRule? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var doc = JsonDocument.ParseValue(ref reader);
        if (doc.RootElement.TryGetProperty("combinator", out _))
        {
            return doc.Deserialize<RuleGroup>(options);
        }

        // other types, validate presence of marker prop, etc.
        return doc.Deserialize<RuleCriteria>(options);
    }

    public override void Write(Utf8JsonWriter writer, BaseRule value, JsonSerializerOptions options) 
        => throw new NotImplementedException();
}

并用它标记基本类:

[JsonConverter(typeof(RuleConverter))]
public class BaseRule;

Full demo @dotnetfiddle

Csharp相关问答推荐

c#处理大量tcp连接

是否可以将gltf转换为字节数组,然后将字节数组转换回文件?

在实际上是List T的 IESEARCH上多次调用First()是否不好?

使用yaml将Azure函数代码部署到FunctionApp插槽时出现问题(zip未找到)

在C#中使用类中的对象值

当通过Google的Gmail Api发送邮件时,签名会产生dkim = neutral(正文散列未验证)'

将轮询与超时同步

使用C#HttpClient以多部分形式数据发送带有非ASCII文件名的文件的问题

C#普罗米修斯指标

net中从位图获取坐标和绘制折线

该函数不能检测两条曲线的交点

正在寻找新的.NET8 Blazor Web应用程序.如何将.js添加到.razor页面?

RabbitMQ群集的MassTransit配置问题

在PostgreSQL上使用ExecuteSqlRawAsync的C#11原始字符串文字有区分大小写的问题

类/值和日期的泛型方法

如何将默认区域性更改为fr-FR而不是en-US?

如何对特定异常使用Polly重试机制?

忽略Visual Studio代码中的StyleCop规则

删除MudRadio时,MudRadioGroup未 Select 正确的MudRadio

如何使用LINQ在C#中填充列表列表?