【问题标题】:Utf8JsonReader.ToString gives: Cannot get the value of a token type 'None'UTF8JSONREADER.TOSTRING给出:无法获得令牌类型的值“无”
【发布时间】:2020-08-07 09:13:51
【问题描述】:

请注意,这是针对 System.Text.Json 而不是 Json.Net,所以 How to unit test a custom 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"));
    }

我需要一个Utf8JsonReader,我需要用string 喂那个。

我试过了:

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

这似乎可行,但在执行reader.GetString() 时会导致转换器崩溃:

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

reader.GetString() 应该是正确的,see Microsoft's example,所以我想我把 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);
}

更新:这也没有回答我的问题:Exception when testing custom JsonConverter。我也试过(从那个答案)没有运气:

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

更新

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

【问题讨论】:

  • 我可能理解错了,但你输入的不是 json 吗?
  • 是的,也试过"\"2019-01-02\"";,但也失败了
  • "\"2019-01-02\"" 不是 json。 Json 必须类似于 { "propName": "2019-01-02" }
  • "2019-01-02" 是有效的 JSON :)(请参阅 jsonlint.com)。我还需要reader.Read();,看看我的回答

标签: c# json .net-core system.text.json


【解决方案1】:

发现问题,

第一个 "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);
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-09-08
  • 2022-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 2021-05-25
  • 2013-02-09
相关资源
最近更新 更多