2

我是 windows phone 8 开发的新手...如何在 windows phone 8 中解析以下数据:

   [
   {
      "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"
            }
         ]
      }
   }
]

我正在尝试通过以下方式解析:

 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; }


        }
    }
}

我能够解析一些数据,但我不知道如何解析选项..请帮助我解析完整的代码。请帮助我解析完整的数据......提前谢谢......

4

3 回答 3

0

这是为您准备的示例转换器类:

// 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();
    }
}

然后options通过以下方式声明字段/属性:

[JsonProperty, JsonConverter( typeof( DictionaryConverter ) )]
public Dictionary<string, string> options;

PS您可能想更改转换器以创建例如Dictionary<int, string>,或其他,而不仅仅是Dictionary<string, string>

于 2013-07-26T17:13:30.670 回答
0

您的代码的问题是您试图将键值对字典解析为对象项数组。

这是不可能的,因为解析引擎会认为 optionid 和 option_name 都是选项列表中每个对象项的属性。如果我们假设这些是属性,则属性必须有一个常量名称,这在您的 json 中不是这种情况。

解析它的唯一可能方法是使用字符串/字符串的键值对字典。您的代码必须是这样的,您应该删除 Options 类。

    [JsonProperty(PropertyName = "options")]
    public Dictionary<string, string> Options { get; set; } 
于 2013-07-26T17:13:47.150 回答
0

几个月前我遇到了类似的问题,基本上 JSON 使用的属性不能直接转换为 C# 属性。因此,经过一些研究,我找到了一种将这些属性反序列化为两个可能选项之一的方法(KeyValuePais 或 Dictioanry 的集合,它将取决于 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;
        }
    }
}

GenericJsonConverter.cs

 /// <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());
    }
}

模型.cs

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);

基本上,我们通过指示如何处理这些边缘情况来定制序列化过程。顺便说一句,如果你想用接口支持你的具体类,GenericJsonConverter 也可以工作。

这是 Windows Phone 8 的代码示例 https://dl.dropboxusercontent.com/u/7193016/stackoverflow/JsonSamplePhoneApp.zip

问候,赫伯

于 2013-08-12T16:24:50.647 回答