C# 反序列化后合并空或不存在的属性及其强类型模型的属性

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

问题是我有一个可以使用我的模型更新的配置,我部署新的更新并且用户不会获得更新的配置文件,因此它将导致空引用异常等。现在我只需设置默认值或使用 new( )使其至少与最新的配置值相似,但这太糟糕了,我需要始终支持它,如果我或其他人甚至忘记合并空属性怎么办?

我有 3 个不同的配置文件(YAML、XML、JSON),但只有一个模型。 我希望它将所有空属性、数组的数组、默认配置中不存在的数组项合并到现有配置、属性的属性等中,但是我想保存反序列化配置中的所有现有内容。

我的模特:

[Serializable]
public class GuardSettings
{
    public GuardSettings()
    {
    }

    public UnturnedGuardOptions UnturnedGuardOptions { get; set; }
    public UnturnedIntegrityVault UnturnedIntegrityVault { get; set; }
    public LocalTimeOptions LocalTimeOptions { get; set; }
    [YamlIgnore, XmlIgnore] public VanillaOptions VanillaOptions { get; set; }
    public LogReport LogReport { get; set; }
    public DiscordWebhookLaunch DiscordWebhookLaunch { get; set; }
    public DiscordWebhookReject DiscordWebhookReject { get; set; }
    public DiscordWebhookAccept DiscordWebhookAccept { get; set; }
    public DiscordWebhookCancel DiscordWebhookCancel { get; set; }
    public DiscordWebhookReport DiscordWebhookReport { get; set; }
    public DiscordWebhookBans DiscordWebhookBans { get; set; }
    public DiscordWebhookUnbans DiscordWebhookUnbans { get; set; }
    public DatabaseOptions DatabaseOptions { get; set; }
    public UnturnedPanelIntegration UnturnedPanelIntegration { get; set; }
    public BanOptions BanOptions { get; set; }
    public PlayerWhitelist PlayerWhitelist { get; set; }
    public HWIDHistory HWIDHistory { get; set; }
    [YamlMember(Alias = "tpsOptions")] public TPSOptions TPSOptions { get; set; }
    public FeaturesOptions FeaturesOptions { get; set; }
    public Feature[] Features { get; set; }
}

[Serializable]
public class Feature
{
    public Feature()
    {
    }

    public string Name { get; set; } = string.Empty;
    public bool Enabled { get; set; }
    public Argument[] Arguments { get; set; } = Array.Empty<Argument>();
}

[Serializable]
public class Argument
{
    public Argument()
    {
    }

    public string? Name { get; set; }
    public object? Value { get; set; }
}

这就是我的看法,我的默认设置只是使用我的自定义工厂来配置默认配置的所有属性(以正确的方式),并且现有设置是来自文件(YAML、XML 或 JSON)的反序列化配置。

private static GuardSettings Merge(GuardSettings defaultSettings, GuardSettings existingSettings)

之后,我想序列化合并的配置以更新配置,以便用户可以更改最新的属性并了解配置中的更改!

我尝试使用Reflection和AutoMapper,但没有成功。

c# serialization merge reflection mapping
1个回答
0
投票

我通常使用的方法是初始化可选属性:

public class MyConfiguration{
    [JsonRequiredAttribute]
    public string MyRequiredProperty {get;set;} // Required property, no default value needed.
    public long MyOptionalProperty {get;set;} = 42; // Optional property, default value needed
}

许多序列化库将替换文件中的

MyOptionalProperty
(如果存在),如果不存在则保留默认值。但请检查您的特定库是否以这种方式工作。通常有某种类型的属性来将属性标记为必需或非必需,因此您可以相当快速地检查所有可选属性是否具有默认值。

如果配置布局发生较大更改,创建新类型可能会很有用,因此您可以反序列化旧类型并手动将其转换为新布局。如果您使用“DTO”,即类型only用于序列化,这会更容易。

反序列化对象,然后将其与默认对象合并似乎有问题。您将需要相当多的复杂反射,并且您将无法处理值类型,即您不知道零是否代表缺失值,或者只是代表设置为零的值。

© www.soinside.com 2019 - 2024. All rights reserved.