首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >System.Text.Json自定义JsonConverter Write()从未调用过

System.Text.Json自定义JsonConverter Write()从未调用过
EN

Stack Overflow用户
提问于 2022-11-18 01:39:08
回答 1查看 28关注 0票数 1

我有一个.NET 6解决方案,在调用JsonObject.ToJsonString()时,我试图重写DateTimeOffset的默认格式,这都是使用本机System.Text.Json库。

我添加了一个定制的DateTimeOffsetConverter

代码语言:javascript
运行
复制
public class DateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
    private readonly string _format;

    public DateTimeOffsetConverter(string format)
    {
        _format = format;
    }

    public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        Debug.Assert(typeToConvert == typeof(DateTimeOffset));
        return DateTimeOffset.Parse(reader.GetString());
    }

    public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(_format));
    }

    public override bool CanConvert(Type typeToConvert)
    {
        return (typeToConvert == typeof(DateTimeOffset));
    }
}

但是,当我尝试使用它时,除了调用构造函数之外,代码永远不会被击中。

我错过了什么阻止JsonConverter被调用的东西?

下面是我的代码,它试图利用这些功能:

代码语言:javascript
运行
复制
[Theory]
[InlineData("New Zealand Standard Time")]
[InlineData("India Standard Time")]
[InlineData("Central Brazilian Standard Time")]
[InlineData("W. Australia Standard Time")]
public void DateTimeOffsetIsSerializedCorrectlyTest(string timeZoneId)
{
    const string DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffzzz";
    var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
    var dateTimeOffset = new DateTimeOffset(DateTimeOffset.Now.DateTime, timeZoneInfo.BaseUtcOffset);

    var json = new JsonObject
    {
        { "value", dateTimeOffset }
    };

    var options = new JsonSerializerOptions
    {
        Converters = { new DateTimeOffsetConverter(DateTimeFormat) }
    };
    string jsonString = json.ToJsonString(options);

    Assert.Contains(jsonString, dateTimeOffset.ToString(DateTimeFormat));
}

有许多密切相关的问题已经张贴,谁的解决方案,我已经试验过,但似乎没有解决我的确切情况。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-27 16:10:05

似乎在DateTimeOffset转换为时应用了转换器,而不是当JsonNode被格式化为string时。因此,您可以通过显式序列化 (您的DateTimeOffset )生成所需的JSON,而不是依赖于隐式转换

代码语言:javascript
运行
复制
var options = new JsonSerializerOptions
{
    Converters = { new DateTimeOffsetConverter(DateTimeFormat) }
};

var json = new JsonObject
{
    { "value", JsonSerializer.SerializeToNode(dateTimeOffset, options) }
};

这导致了{"value":"2022-11-27T15:10:23.570\u002B12:00"}。注意,+是转义的。如果您要求它不被转义以使您的Assert.Contains(jsonString, dateTimeOffset.ToString(DateTimeFormat));成功通过,请使用UnsafeRelaxedJsonEscaping

代码语言:javascript
运行
复制
var formattingOptions = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    // Other formatting options as required, e.g.
    //WriteIndented = true, // This option also seems to be applied when the JsonNode is formatted to a string, rather than when it is constructed
};

string jsonString = json.ToJsonString(formattingOptions);

这导致了{"value":"2022-11-27T15:17:44.142+12:00"}

演示小提琴#1 这里

备注:

  • 文档页JsonSerializerOptions声明: 可以使用JsonSerializer序列化和反序列化JsonNode实例。但是,如果使用采用JsonSerializerOptions的重载,则选项实例仅用于获取自定义转换器。没有使用选项实例的其他功能。..。

这条语句似乎不正确;即使用DateTimeOffsetConverter序列化JsonNode层次结构,也不会提取您的JsonSerializer.Serialize(json, options)

演示小提琴#2 这里

  • 我找不到任何文档列出在JsonNode构造和JsonNode字符串格式化过程中应用的选项。文档确实显示了在字符串格式设置期间应用。。一些实验表明,此外,在字符串格式化过程中还应用了Encoder和(令人惊讶的) NumberHandling。 演示小提琴#3 这里
  • 一些调试显示了为什么在字符串格式设置期间不应用DateTimeOffsetConverter隐式转换算子: JsonNode节点= dateTimeOffset; 返回类型为JsonValueTrimmable的对象。这种类型包括它自己的内部转换器: 内部密封部分类JsonValueTrimmable : JsonValue {专用只读JsonTypeInfo?_jsonTypeInfo;私有只读JsonConverter?_converter; 如果我们使用反射访问_converter的值,我们会发现它被初始化为系统转换器DateTimeOffsetConverter: Console.WriteLine("JsonValueTrimmable._converter = {0}",fi.GetValue(节点));//打印System.Text.Json.Serialization.Converters.DateTimeOffsetConverter 此系统转换器忽略传入选项,只需调用Utf8JsonWriter.WriteStringValue(DateTimeOffset);。 演示小提琴#4 这里
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74484057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档