我为我的项目使用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)。
答案 0 :(得分:0)
这里存在多个问题,其中一些可能导致您描述的症状:
您的数据模型与JSON的数据模型不匹配。 self
是_links
而非Streams
的属性。 channel
和_links
中的stream
属性显示Streams
。
您的班级Streams
包含DataMember
属性Stream
,这是一个抽象类。当然这不能反序列化。也许你忘了把它包含在你的问题中?
您的_links
字典采用“简单”字典格式,即DataContractJsonSerializerSettings.UseSimpleDictionaryFormat = true
。您需要使用此设置(仅限.Net 4.5或更高版本),或切换为JavaScriptSerializer
或Json.NET。
您使用的ASCII encoding仅限于最低128个Unicode字符。请改用Encoding.Unicode
。
要解决此问题,您需要:
转到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; }
}
完成此操作后,您现在可以使用JavaScriptSerializer
或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);
在这两种情况下,您都会看到字典内容存在。
如果您想使用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 });