【问题标题】:Member class not serializing the defined way成员类未序列化定义的方式
【发布时间】:2021-09-21 16:54:38
【问题描述】:

如何确保另一个类中的自定义类在定义时被序列化?

我有一堂课:

public class Event
{
    public string Type { get; set; }
    public DateTime Timestamp { get; set; }

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this, Utils.IsoDateTimeConverter());
    }
}

IsoDateTimeConverter() 是这样定义的:

public static class Utils
{
    private static IsoDateTimeConverter isoDateTimeConverter = null;

    public static IsoDateTimeConverter IsoDateTimeConverter()
    {
        if (isoDateTimeConverter == null)
        {
            isoDateTimeConverter = new IsoDateTimeConverter
            {
                DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ";
            };
        }

        return isoDateTimeConverter;
    }
}

如果我在 Event 对象上调用 .ToString(),则项目会正确序列化(TimeStamp 的格式正确,即我定义的格式):

var testEvent = new Event() { Type = "Test", Timestamp = new DateTime(2021, 7, 12, 11, 6, 36, 0) };
var result = testEvent.ToString();

结果

{
   "Type":"Test",
   "Timestamp":"2021-07-12T11:06:36.0000000Z"
}

如果我围绕 Event 创建一个包装类 UserEvent,并尝试对其进行序列化,则 Event 类的序列化方式不同:

public class UserEvent
{
    public string UserId { get; set; }
    public Event Event { get; set; }

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }
}
// Example of usage:
var testEvent = new Event() { Type = "Test", Timestamp = new DateTime(2021, 7, 12, 11, 6, 36, 0);
var testUserEvent = new UserEvent(){UserId = "TestId", Event = testEvent};
var result = testUserEvent.ToString();

结果

{
   "UserId":"TestUserId",
   "Event":{
      "Type":"Test",
      "Timestamp":"2021-07-12T11:06:36"
   }
}    

请注意,时间戳的格式与以前不同。

如何确保当 Event 在另一个类中时它被正确序列化?

编辑 1:我知道如果我将 UserEvent 序列化为 JsonConvert.SerializeObject(this, Utils.IsoDateTimeConverter()),输出将符合预期,但我不想这样做,因为我不希望包装类知道内部类的样子以及它应该如何序列化。内部类应该按照它在其中定义的方式进行序列化。

【问题讨论】:

    标签: c# serialization json.net jsonconvert


    【解决方案1】:

    我建议创建一个自定义 IsoDateTimeConverter 类,在其中覆盖 DateTimeFormat

    public class CustomIsoDateTimeConverter: IsoDateTimeConverter 
    {
        public CustomIsoDateTimeConverter()
        {
           DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ";
        }
    }
    

    你可以在没有工厂方法的情况下使用这个类(比如IsoDateTimeConverter()

    您可以使用JsonConverterAttribute 来装饰您的Timestamp 属性:

    public class Event
    {
        public string Type { get; set; }
        [JsonConverter(typeof(CustomIsoDateTimeConverter))]
        public DateTime Timestamp { get; set; }
    }
    

    我建议从两个类中删除 ToString 覆盖。您可能需要以不同的格式序列化相同的数据,那么您将遇到麻烦。

    var testEvent = new Event() { Type = "Test", Timestamp = new DateTime(2021, 7, 12, 11, 6, 36, 0) };
    var testUserEvent = new UserEvent(){UserId = "TestId", Event = testEvent};
    var result = JsonConvert.SerializeObject(testUserEvent);
    

    结果

    {
       "UserId":"TestId",
       "Event":{
          "Type":"Test",
          "Timestamp":"2021-07-12T11:06:36.0000000Z"
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-04
      • 2014-06-07
      • 1970-01-01
      • 2015-07-20
      • 2021-04-16
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多