Utf8JsonReader.ToString 给出:无法获取令牌类型“None”的值

Jul*_*ian 3 c# json .net-core system.text.json

请注意,这是针对 System.Text.Json 而不是 Json.Net,因此如何对自定义 JsonConverter 进行单元测试不是重复的。

我喜欢对我的自定义 JsonConverter 进行单元测试:

using System.Text.Json;

public class DateTimeShortConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // support yyyy-MM-dd but also with times
        return DateTime.Parse(reader.GetString());
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
    }

Run Code Online (Sandbox Code Playgroud)

我需要一个Utf8JsonReader,并且我需要用一个来喂养那个string

我试过这个:

byte[] bytes = Encoding.UTF8.GetBytes("2019-01-02");
var reader = new Utf8JsonReader(bytes.AsSpan());
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但在执行以下操作时会导致转换器崩溃reader.GetString()

System.InvalidOperationException:无法以字符串形式获取令牌类型“None”的值。在 System.Text.Json.Utf8JsonReader.GetString()

应该reader.GetString()是正确的,请参阅微软的示例,所以我认为我喂Utf8JsonReader错了。

reader.Position是只读的,因此这也不是一个选项。如何正确地向 Utf8JsonReader 提供字符串?

全面测试:

using System;
using System.Text;
using System.Text.Json;
Using Xunit;

[Fact]
public void ReadDateTimeTests()
{
    // Arrange
    var input = "2019-01-02";

    var dateTimeShortConverter = new DateTimeShortConverter();
    byte[] bytes = Encoding.UTF8.GetBytes(input);
    var reader = new Utf8JsonReader(bytes.AsSpan());

    Type typeToConvert = typeof(DateTime);
    JsonSerializerOptions options = new JsonSerializerOptions();

    var expected = new DateTime(2019, 01, 02);

    // Act
    var result = dateTimeShortConverter.Read(ref reader, typeToConvert, options);

    // Assert
    Assert.Equal(expected, result);
}

Run Code Online (Sandbox Code Playgroud)

更新:这也没有回答我的问题:测试自定义 JsonConverter 时出现异常。我也尝试过(从那个答案)但没有运气:

byte[] bytes = Encoding.UTF8.GetBytes(input);
var reader = new Utf8JsonReader(bytes.AsSpan(), false, new JsonReaderState(new JsonReaderOptions()));
Run Code Online (Sandbox Code Playgroud)

更新

"2019-01-02"在 C# 中不是正确的 JSON,但"\"2019-01-02\""它仍然给出相同的错误。

Jul*_*ian 5

发现问题了,

首先"2019-01-02"是有效的 JSON,但不是2019-01-02,所以我需要在那里进行转义。

之后,我需要一次读取来读取字符串的引用:reader.Read();

所以这有效:

using System;
using System.Text;
using System.Text.Json;
Using Xunit;

[Fact]
public void ReadDateTimeTests2()
{
    // Arrange
    var input = "\"2019-01-02\"";

    var dateTimeShortConverter = new DateTimeShortConverter();
    byte[] bytes = Encoding.UTF8.GetBytes(input);
    var reader = new Utf8JsonReader(bytes.AsSpan());
    reader.Read(); // Read the quote

    Type typeToConvert = typeof(DateTime);
    JsonSerializerOptions options = new JsonSerializerOptions();

    var expected = new DateTime(2019, 01, 02);

    // Act
    var result = dateTimeShortConverter.Read(ref reader, typeToConvert, options);

    // Assert
    Assert.Equal(expected, result);
}
Run Code Online (Sandbox Code Playgroud)