C# 在windows phone 8中解析复杂的JSON对象(字典键/值对)
我是windows phone 8开发新手…如何在windows phone 8中解析以下数据:C# 在windows phone 8中解析复杂的JSON对象(字典键/值对),c#,json,windows-phone-7,json.net,C#,Json,Windows Phone 7,Json.net,我是windows phone 8开发新手…如何在windows phone 8中解析以下数据: [ { "detail":{ "single_selection":[ { "Questions":"If -2<1\/2x< 4 , then", "Question Type":"text", "Url":"NO URL",
[
{
"detail":{
"single_selection":[
{
"Questions":"If -2<1\/2x< 4 , then",
"Question Type":"text",
"Url":"NO URL",
"options":{
"2379":"4 > x < -8",
"2380":"4 < x > -8",
"2381":"4 < x < -8",
"2382":"4 > x > -8"
},
"correct Ans":[
"2382"
],
"marks":"1",
"description":"4 > x > -8"
}
]
}
}
]
[
{
“细节”:{
“单一选择”:[
{
“问题”:“如果-2 x<-8”,
“2380”:“4-8”,
“2381”:“4x>-8”
},
“正确答案”:[
"2382"
],
“标记”:“1”,
“说明”:“4>x>-8”
}
]
}
}
]
我尝试用以下方式解析它:
namespace TestSample
{
public partial class MainPage : PhoneApplicationPage
{
private const string Con_String = @"isostore:/DataBase.sdf";
// Constructor
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(new Uri("SomeURL"));
}
public void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var rootObject = JsonConvert.DeserializeObject<RootObject1[]>(e.Result);
foreach (var r in rootObject)
{
var s = r.detail.single_selection;
for (int i = 0; i < s.Count; i++)
{
}
}
}
public class RootObject1
{
public Detail detail { get; set; }
[JsonProperty("total questions and marks")]
public List<TotalQuestionsAndMark> totalquestionsandmarks { get; set; }
}
public class TotalQuestionsAndMark
{
[JsonProperty("total questions")]
public int totalquestions { get; set; }
[JsonProperty("total test marks")]
public int totaltestmarks { get; set; }
public string Duration { get; set; }
}
public class Detail
{
public List<SingleSelection> single_selection { get; set; }
}
public class SingleSelection
{
public string Questions { get; set; }
[JsonProperty("Question Type")]
public string QuestionType { get; set; }
public string Url { get; set; }
public string marks { get; set; }
public string description { get; set; }
public Options option { get; set; }
[JsonProperty("correct Ans")]
public List<string> correctAns { get; set; }
}
public class Options
{
public string optionid { get; set; }
public string option_name { get; set; }
}
}
}
[JsonProperty, JsonConverter( typeof( DictionaryConverter ) )]
public Dictionary<string, string> options;
名称空间测试示例
{
公共部分类主页:PhoneApplicationPage
{
private const string Con_string=@“isostore:/DataBase.sdf”;
//建造师
公共主页()
{
初始化组件();
已加载+=新路由EventHandler(主页面_已加载);
}
已加载无效主页(对象发送器、路由目标)
{
WebClient WebClient=新的WebClient();
webClient.DownloadStringCompleted+=新的DownloadStringCompletedEventHandler(webClient\u DownloadStringCompleted);
下载StringAsync(新Uri(“SomeURL”);
}
public void webClient_DownloadStringCompleted已完成(对象发送方,DownloadStringCompletedEventArgs e)
{
var rootObject=JsonConvert.DeserializeObject(例如Result);
foreach(rootObject中的var r)
{
var s=r.详细信息.单一选择;
对于(int i=0;i
我能够解析一些数据,但我不知道如何解析选项。。请帮我分析完整的代码。请帮我分析完整的数据。。。Thanx Previous…以下是为您提供的示例转换器类:
// Warning: untested code
public class DictionaryConverter: JsonConverter
{
public override bool CanRead { get { return true; } }
public override bool CanWrite { get { return false; } }
public override bool CanConvert( Type objectType )
{
return objectType == typeof( Dictionary<string, string> );
}
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
{
// Load JObject from stream
JObject jObject = JObject.Load( reader );
Dictionary<string, string> res = new Dictionary<string, string>( jObject.Count );
foreach( var kvp in jObject )
res[ kvp.Key ] = (string)kvp.Value;
return res;
}
public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer )
{
throw new NotSupportedException();
}
}
另外,您可能希望更改转换器以创建例如
字典
,或其他任何内容,而不仅仅是字典
代码的问题是您试图将键值对字典解析为对象项数组
这是不可能的,因为解析引擎会认为optionid和option_name都是选项列表中每个对象项上的属性。如果我们假设这些是属性,那么属性必须有一个常量名称,而json中不是这样
唯一可能的解析方法是使用字符串/字符串的键值对字典。
您的代码必须是这样的,您应该删除Options类
[JsonProperty(PropertyName = "options")]
public Dictionary<string, string> Options { get; set; }
[JsonProperty(PropertyName=“options”)]
公共字典选项{get;set;}
几个月前我遇到了类似的问题,基本上JSON使用的属性不能直接转换为C#属性。因此,经过一些研究,我发现了一种方法,可以将这些属性反序列化为两种可能的选项之一(KeyValuePai的集合或字典,这取决于JSON哪个选项更适合)
顺便说一句,我正在使用Json.NET库,它允许我自定义反序列化过程
以下是我正在使用的文件:
用于检索内容
JsonRetriever.cs
使用Newtonsoft.Json;
使用制度;
使用System.Threading.Tasks
static class JsonRetriever
{
public async static Task<T> GetJsonFromUri<T>(string uriString)
{
var uri = new Uri(uriString);
return await GetJsonFromUri<T>(uri);
}
public async static Task<T> GetJsonFromUri<T>(Uri uri)
{
var webRequest = System.Net.WebRequest.CreateHttp(uri);
using (var webResponse = await Task<System.Net.WebResponse>.Factory.FromAsync(webRequest.BeginGetResponse, webRequest.EndGetResponse, TaskCreationOptions.None))
{
using (var stream = webResponse.GetResponseStream())
{
return GetJson<T>(stream);
}
}
}
public static T GetJson<T>(System.IO.Stream stream)
{
using (var streamReader = new System.IO.StreamReader(stream))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var jsonSerializer = JsonSerializer.CreateDefault();
var instanceOfT = jsonSerializer.Deserialize<T>(jsonTextReader);
return instanceOfT;
}
}
}
public static T GetJson<T>(System.String json)
{
using (System.IO.TextReader textReader = new System.IO.StringReader(json))
{
var jsonSerializer = JsonSerializer.CreateDefault();
var instanceOfT = (T)jsonSerializer.Deserialize(textReader, typeof(T));
return instanceOfT;
}
}
}
静态类JsonRetriever
{
公共异步静态任务GetJsonFromUri(字符串URI字符串)
{
var uri=新uri(uriString);
返回等待GetJsonFromUri(uri);
}
公共异步静态任务GetJsonFromUri(Uri)
{
var webRequest=System.Net.webRequest.CreateHttp(uri);
使用(var webResponse=wait Task.Factory.fromsync(webRequest.BeginGetResponse、webRequest.EndGetResponse、TaskCreationOptions.None))
{
使用(var stream=webResponse.GetResponseStream())
{
返回GetJson(流);
}
}
}
公共静态T GetJson(System.IO.Stream)
{
使用(var streamReader=new System.IO.streamReader(stream))
{
使用(var jsonTextReader=new jsonTextReader(streamReader))
{
var jsonSerializer=jsonSerializer.CreateDefault();
var instanceOfT=jsonSerializer.Deserialize(jsonTextReader);
返回instanceOfT;
}
}
}
公共静态T GetJson(System.String json)
{
使用(System.IO.TextReader TextReader=new System.IO.StringReader(json))
{
var jsonSerializer=jsonSerializer.CreateDefault();
/// <summary>
/// Indicates to Newtonsoft.Json how to deserialize:
/// - interfaces to concrete classes
/// - how to deserialize collections of interfaces to concrete classes
/// - how to deserialize collections of KeyValuePairs (for non-valid identifiers JSON properties) into Dictionary or Collections
/// See:
/// http://stackoverflow.com/questions/5780888/casting-interfaces-for-deserialization-in-json-net
/// http://stackoverflow.com/questions/9452901/cannot-deserialize-json-array-into-type-json-net
/// </summary>
/// <typeparam name="TInterface"></typeparam>
/// <typeparam name="TConcrete"></typeparam>
public class GenericJsonConverter<TInterface, TConcrete> : JsonConverter where TConcrete : TInterface
{
public override bool CanConvert(Type objectType)
{
return
objectType == typeof(Collection<TInterface>)
|| objectType == typeof(TInterface)
|| objectType == typeof(Collection<KeyValuePair<string, TInterface>>)
|| objectType == typeof(Dictionary<string, TInterface>)
;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (objectType == typeof(Collection<TInterface>))
{
return new Collection<TInterface>(serializer.Deserialize<Collection<TConcrete>>(reader).OfType<TInterface>().ToList());
}
if (objectType == typeof(TInterface))
{
return serializer.Deserialize<TConcrete>(reader);
}
if ((objectType == typeof(Collection<KeyValuePair<string, TInterface>>))
|| (objectType == typeof(Dictionary<string, TInterface>)))
{
var isDictionary = (objectType == typeof(Dictionary<string, TInterface>));
Collection<KeyValuePair<string, TInterface>> deserializedObject = new Collection<KeyValuePair<string, TInterface>>();
reader.Read(); // Skips the '{' token at the beginning of the JSON object
while (reader.TokenType == JsonToken.PropertyName)
{
var id = reader.Value.ToString(); // Contains the property value => for invalid JSONs properties it's an ID (e.g. number or GUID)
reader.Read(); // Skips the '{' token of the inner object
var instaceOfConcreteType = serializer.Deserialize<TConcrete>(reader);
deserializedObject.Add(new KeyValuePair<string, TInterface>(id, instaceOfConcreteType));
reader.Read(); // Skips the '{' token at the beginning of the JSON object
}
var result = isDictionary ? deserializedObject.ToDictionary(kvp => kvp.Key, kvp => kvp.Value) : (object)deserializedObject;
return result;
}
throw new NotSupportedException("Cannot Deserialize type:" + objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
return;
// TODO: Verify if value.GetType() is compatible with TConcrete before forcing a cast
if (value.GetType() == typeof(TInterface))
serializer.Serialize(writer, (TConcrete)value);
throw new NotSupportedException("Cannot serialize type:" + value.GetType());
}
}
public class SingleSelection
{
public string Questions { get; set; }
public string Url { get; set; }
public string marks { get; set; }
public string description { get; set; }
[JsonConverter(typeof(GenericJsonConverter<string, string>))]
public Dictionary<string, string> options { get; set; }
[JsonProperty("Question Type")]
public string QuestionType { get; set; }
[JsonProperty("correct Ans")]
public List<string> correctAns { get; set; }
}
public class Detail
{
public List<SingleSelection> single_selection { get; set; }
}
public class RootObject
{
public Detail detail { get; set; }
}
var rootObject = JsonRetriever.GetJson<List<RootObject>>(AppResources.SampleJson);