0

我为我的项目使用 Twitch API,我需要在以下位置获取 _links 值:https ://api.twitch.tv/kraken/streams/ogaminglol (示例)

我使用这段代码:

WebClient strJson = new WebClient();
string test = strJson.DownloadString("https://api.twitch.tv/kraken/streams/ogaminglol");
DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(Streams));
MemoryStream ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(test));
Streams stream = (Streams)js.ReadObject(ms);
//label1.Text = "Title : " + stream.game;
ms.Close();

还有我接收数据的 Streams 类

[DataContract]
class Streams
{
    [DataMember]
    public Dictionary<string, string> _links { get; set; }

    [DataMember]
    public string self { get; set; }

    [DataMember]
    public string channel { get; set; }

    [DataMember]
    public Stream stream { get; set; }
}

自我和频道为空,因为在https://api.twitch.tv/kraken/streams/ogaminglol中,它们位于“_links”部分。我试过字典但没有成功。我希望你理解我的问题(和我的英语:p)。

4

1 回答 1

0

这里有多个问题,其中几个可能导致您描述的症状:

  1. 您的数据模型与 JSON 的数据模型不匹配。 self_linksnot的属性Streamschannel显示为 in_linksstreamnot的属性Streams

  2. 您的类Streams包含一个抽象类的DataMember属性。Stream当然这不能反序列化。也许您忘记将其包含在您的问题中?

  3. 您的_links字典采用“简单”字典格式,即DataContractJsonSerializerSettings.UseSimpleDictionaryFormat = true. 您需要使用此设置(仅限 .Net 4.5 或更高版本),或切换到JavaScriptSerializerJson.NET

  4. 您正在使用ASCII 编码,该编码仅限于最低 128 个 Unicode 字符。改为使用Encoding.Unicode

  5. WebClient是一次性的,所以应该在using语句中实例化。

要解决此问题,您需要:

  1. 转到http://json2csharp.com/,发布您的 JSON,并让它为您生成类,然后将所有_links属性转换为public Dictionary<string, string> _links { get; set; }. 你应该得到这个:

    public class Streams
    {
        public Dictionary<string, string> _links { get; set; }
    
        public Stream stream { get; set; }
    }
    
    public class Stream
    {
        public long _id { get; set; }
        public string game { get; set; }
        public int viewers { get; set; }
        public string created_at { get; set; }
        public Dictionary<string, string> _links { get; set; }
        public Preview preview { get; set; }
        public Channel channel { get; set; }
    }
    
    public class Channel
    {
        public Dictionary<string, string> _links { get; set; }
        public object background { get; set; }
        public object banner { get; set; }
        public string broadcaster_language { get; set; }
        public string display_name { get; set; }
        public string game { get; set; }
        public string logo { get; set; }
        public bool mature { get; set; }
        public string status { get; set; }
        public bool partner { get; set; }
        public string url { get; set; }
        public string video_banner { get; set; }
        public int _id { get; set; }
        public string name { get; set; }
        public string created_at { get; set; }
        public string updated_at { get; set; }
        public int delay { get; set; }
        public int followers { get; set; }
        public string profile_banner { get; set; }
        public string profile_banner_background_color { get; set; }
        public int views { get; set; }
        public string language { get; set; }
    }
    
    public class Preview
    {
        public string small { get; set; }
        public string medium { get; set; }
        public string large { get; set; }
        public string template { get; set; }
    }
    
  2. 完成此操作后,您现在可以使用JavaScriptSerializerJson.NET 或 Json.NET 立即反序列化您的 JSON:

        string test;
        using (WebClient strJson = new WebClient())
        {
            test = strJson.DownloadString("https://api.twitch.tv/kraken/streams/ogaminglol");
        }
    
        var streams1 = JsonConvert.DeserializeObject<Streams>(test);
    
        var streams2 = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Streams>(test);
    

    在这两种情况下,您都会看到字典内容存在。

  3. 如果您想使用DataContractJsonSerializer并在 .Net 4.5 或更高版本中工作,则需要以下辅助方法:

    private static MemoryStream GenerateStreamFromString(string value)
    {
        return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
    }
    
    public static T GetObject<T>(string json) where T : class
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
        return GetObject<T>(json, serializer);
    }
    
    public static T GetObject<T>(string json, DataContractJsonSerializerSettings settings) where T : class
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), settings);
        return GetObject<T>(json, serializer);
    }
    
    public static T GetObject<T>(string json, DataContractJsonSerializer serializer)
    {
        using (var stream = GenerateStreamFromString(json))
        {
            return (T)serializer.ReadObject(stream);
        }
    }
    

    然后像这样称呼它:

        var streams3 = DataContractJsonSerializerHelper.GetObject<Streams>(test, new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true });
    
于 2015-02-08T20:57:49.103 回答