【问题标题】:How to serialize and deserialize an object as a string?如何将对象序列化和反序列化为字符串?
【发布时间】:2022-11-15 23:22:22
【问题描述】:

我想将 C# 对象序列化(和反序列化)为 json 字符串。 通常当对象被序列化时,对象被包含在生成的json中的一对{}中。 但是在这里,我对仅序列化为字符串的对象感兴趣。

我有兴趣这样做来封装有关如何格式化 ItemNumbers 的逻辑。 但我不想公开我正在为 ItemNumber 使用类而不是普通字符串的事实。

这是我正在寻找的一个例子。 类ItemNumber 包含在类Item 中。

public class ItemNumber
{
    private string _value;

    public ItemNumber(string num)
    {
        _value = num;
    }
}

public class Item
{
    public ItemNumber ItemNumber { get; set; }
}

public void Main()
{
    var itemNumber = new ItemNumber("ABC-1234");
    var item = new Item
    {
        ItemNumber = itemNumber,
    };

    var json = System.Text.Json.JsonSerializer.Serialize(item);
}

我希望将 Item 序列化为如下所示的 json:

{
    "itemNumber": "ABC-1234" // <- Notice, not an object. Just a string
}

我知道我可能必须实现自定义序列化程序,但该指南发现似乎假设 C# 对象应始终序列化为 json 对象。

如何实现我正在寻找的序列化逻辑?

【问题讨论】:

  • 您使用的是哪个 JSON 库,Newtonsoft 还是 System.Text.Json?
  • “ABC-1234”来自哪里,“_value”有什么用?你能发布你到目前为止所做的代码吗?
  • Item 类是一个对象,下面是字典。为什么不serialize Item 课程会给你想要的结果?
  • 我正在使用 System.Text。我已经用这些信息编辑了我的问题,并添加了一个我想如何使用该类的示例。
  • 使用 Newtonsoft.Json 的代码会简单得多。 Text.Json 几乎所有内容都需要自定义格式化程序,除了“Hello World!”演示。

标签: c# json serialization


【解决方案1】:

我不知道你为什么不这样做???
如果要允许对象的值可以为空,请添加 ?

public class ItemNumber
{
    public string? Number { get; set; }

    public ItemNumber(string itemNumber)
    {
        this.Number = itemNumber;
    }
}
public class Item
{
    //Can be any data type / object
    public int? ItemNumber { get; set; }
    public List<int>? ItemNumbers { get; set; }
    public ItemNumber? Number { get; set; }
}

接着...

//Where ever you're populating the object
var itemNumbers = new Item
{
    ItemNumber = 1,
    ItemNumbers = new List<int> { 1, 2, 3, 4 },
    Number = new ItemNumber("ABC-1234")
};

//Write this output to a new file or and existing one to update it.
var output = JsonConvert.SerializeObject(itemNumbers);
/* Output
 * {
 *     "ItemNumber": 1,
 *     "ItemNumbers": [1,2,3,4],
 *     "Number": {"Number":"ABC-1234"}
 * }
 */

编辑: 强烈推荐使用Newtonsoft

【讨论】:

  • 嗨,我已经增加了我为什么对这个问题感兴趣的动机。不能有多个 ItemNumbers pr。物品。
  • 如果您希望 json 看起来像这样 { "itemNumber": "ABC-1234" // &lt;- Notice, not an object. Just a string },那么不要在您的 serializing 类中使用对象,因为它被归类为对象,并且总是像我的 Output 示例一样输出。如果您希望它只是 string key : string value,请创建一个仅包含字符串 ItemNumber 的对象
【解决方案2】:

the System.Text.Json documentation 中解释了如何执行此操作的答案。实现一个自定义转换器并在序列化期间使用它。

注意:在您的示例中,无法从 ItemNumber 中提取值,我实现了 ToString 方法。

public class ItemNumber
{
    private string _value;

    public ItemNumber(string num)
    {
        _value = num;
    }

    public override string ToString()
    {
        return _value;
    }
}

public class Item
{
    // rename output property
    [JsonPropertyName("itemNumber")]
    // use custom converter
    [JsonConverter(typeof(ItemNumberJsonConverter))]
    public ItemNumber ItemNumber { get; set; }
}

public class ItemNumberJsonConverter : JsonConverter<ItemNumber>
{
    public override ItemNumber Read(
        ref Utf8JsonReader reader,
        Type typeToConvert,
        JsonSerializerOptions options) =>
            new ItemNumber(reader.GetString()!);

    public override void Write(
        Utf8JsonWriter writer,
        ItemNumber val,
        JsonSerializerOptions options) => writer.WriteStringValue(val.ToString());
}

internal class Program
{
    static void Main(string[] args)
    {
        var itemNumber = new ItemNumber("ABC-1234");
        var item = new Item
        {
            ItemNumber = itemNumber,
        };

        var serializeOptions = new JsonSerializerOptions
        {
            WriteIndented = true,
        };

        var json = System.Text.Json.JsonSerializer.Serialize(item, serializeOptions);

        Console.WriteLine(json);
    }
}

控制台输出

{
  "itemNumber": "ABC-1234"
}

【讨论】:

    猜你喜欢
    • 2020-10-19
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多