【问题标题】:how to deal with JSON that changes?如何处理发生变化的 JSON?
【发布时间】:2018-09-08 06:08:24
【问题描述】:

由于我是新手,我很抱歉我的无知。我需要检查抽搐流是否直播。我通过使用HttpClient 和GET 请求来做到这一点。 TwitchData 将 JSON 反序列化为对象的类如下。

public partial class TwitchData
{
    [JsonProperty("data")]
    public Datum[] Data { get; set; }

    [JsonProperty("pagination")]
    public Pagination Pagination { get; set; }
}

public partial class Datum
{
    [JsonProperty("id")]
    public string Id { get; set; }

    [JsonProperty("user_id")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long UserId { get; set; }

    [JsonProperty("game_id")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long GameId { get; set; }

    [JsonProperty("community_ids")]
    public object[] CommunityIds { get; set; }

    [JsonProperty("type")]
    public string Type { get; set; }

    [JsonProperty("title")]
    public string Title { get; set; }

    [JsonProperty("viewer_count")]
    public long ViewerCount { get; set; }

    [JsonProperty("started_at")]
    public DateTimeOffset StartedAt { get; set; }

    [JsonProperty("language")]
    public string Language { get; set; }

    [JsonProperty("thumbnail_url")]
    public string ThumbnailUrl { get; set; }
}

public partial class Pagination
{
    [JsonProperty("cursor")]
    public string Cursor { get; set; }
}

public partial class TwitchData
{
    public static TwitchData FromJson(string json) => JsonConvert.DeserializeObject<TwitchData>(json, QuickType.Converter.Settings);
}

public static class Serialize
{
    public static string ToJson(this TwitchData self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}

internal static class Converter
{
    public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
        Converters = {
            new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
        },
    };
}

internal class ParseStringConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null) return null;
        var value = serializer.Deserialize<string>(reader);
        long l;
        if (Int64.TryParse(value, out l))
        {
            return l;
        }
        throw new Exception("Cannot unmarshal type long");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        if (untypedValue == null)
        {
            serializer.Serialize(writer, null);
            return;
        }
        var value = (long)untypedValue;
        serializer.Serialize(writer, value.ToString());
        return;
    }

    public static readonly ParseStringConverter Singleton = new ParseStringConverter();
}

我用这个做请求

HttpClient client = new HttpClient();
string uri = "https://api.twitch.tv/helix/streams?user_id=59980349";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Client-ID", token);
var result = client.GetStringAsync(uri);
jsonString = result.ToString();
twitchData = PwdResetRequest.FromJson(jsonString);

这样做的问题是,如果流离线,JSON 会发生变化,从而使写入的类 TwitchData 无法用于 JsonConvert.DeserializeObject。

以下是流在线和离线时的 JSON。

{
  "data": [
    {
      "id": "30356128676",
      "user_id": "59788312",
      "game_id": "498652",
      "community_ids": [],
      "type": "live",
      "title": "A stream",
      "viewer_count": 1325,
      "started_at": "2018-09-07T16:30:09Z",
      "language": "en",
      "thumbnail_url": "url"
    }
  ],
  "pagination": {
    "cursor": "eydBIjpwdWGsLaJhIjp7IkGH4hNl6CH6MXr9"
  }
}

当它离线时

{
  "data": [],
  "pagination": {}
}

【问题讨论】:

  • 可能从服务器返回的 JSON 数据不是标准的 JSON 对象。
  • 使这些属性可以为空并在您的转换器中进行空检查可能会有所帮助。
  • 您可以尝试动态反序列化,每次只访问您需要的字段。有几个堆栈溢出帖子涵盖了这个主题。
  • 我无法重现您的问题,请参阅dotnetfiddle.net/HOa4dg。我能找到的唯一问题是var twitchData = PwdResetRequest.FromJson(jsonString); 应该是var twitchData = TwitchData.FromJson(jsonString);
  • 另外,在ParseStringConverter 中,您应该使用NumberFormatInfo.InvariantInfo 进行解析。但我怀疑这就是问题所在。

标签: c# json xamarin xamarin.forms


【解决方案1】:

我找到了解决问题的方法。我正在创建的对象有 2 个变量,Datum[] dataPagination Pagination。坦率地说,如果流离线,只有 JSON 字符串的变化(可以在问题中看到)是数据数组和分页块都是空的。通过检查这些变量的长度条件(检查其中一个就足够了),我可以决定流是实时的还是离线的。比如getStreams类,

if (getStreams.Datum.Length != 0) {
return true;
}
else {
return false;
}

【讨论】:

    猜你喜欢
    • 2011-07-15
    • 2021-10-31
    • 1970-01-01
    • 2016-02-13
    • 2020-05-09
    • 2015-05-18
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多