当名称有括号和圆括号时反序列化JSON

本文关键字:圆括号 反序列化 JSON | 更新日期: 2023-09-27 18:02:41

我正在使用来自第三方的JSON,看起来像这样:

 {"id":"1","[question(21), option('"10033-other'")]":"","[question(22)]":"electric"}

我明白如何得到值时,关键字名称是一个简单的字符串。但我无法弄清楚如何得到值时,关键字的名称不是一个基本的字符串。我该如何反序列化[问题(21)]和[问题(22)]值?

我的代码如下。

类:

public class MyFeed
{
    public string id { get; set; }
}
public class MyFeedClass
{
    public List<MyFeed> data { get; set; }
}

Program.cs

    static void Main(string[] args)
    {
        string webReq = String.Empty;
        webReq += "https://restapi.surveygizmo.com/head/survey/zzzzzzzzz";
        webReq += "/surveyresponse/";
        webReq += "?user:pass=xxxxxx:yyyyyyyyy";
        HttpWebRequest request = WebRequest.Create(webReq) as HttpWebRequest;
        var myString = String.Empty;
        using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
        {
            StreamReader reader = new StreamReader(response.GetResponseStream());
            myString += reader.ReadToEnd();
        }        
        MyFeedClass myFeedClass = 
            new JavaScriptSerializer().
            Deserialize<MyFeedClass>(myString);
        Console.Title = "Bentley - Survey Data Loader";
        Console.WriteLine("");
        foreach (var item in myFeedClass.data)
        {
            Console.WriteLine("id: {0}", item.id);
        }
        Console.WriteLine("");
        Console.WriteLine("Press enter to exit...");
        Console.ReadLine();
    }

当名称有括号和圆括号时反序列化JSON

你的JSON和你的类看起来不匹配——也就是说,稍微调整一下,你可以得到一些来反序列化:

如果我们像这样包装你发布的JSON:

string data =  @"{""data"":{""id"":""1"",""[question(21), option('""10033-other'"")]"":"""",""[question(22)]"":""electric""}}";

(或非格式)

{"data":{"id":"1","[question(21), option('"10033-other'")]":"","[question(22)]":"electric"}}

并这样重新定义提要类:

public class MyFeedClass
{
    public Dictionary<string,string> data { get; set; }
}
new JavaScriptSerializer().Deserialize<MyFeedClass>(data)

生成内容为

Dictionary<string,string>
{id, 1 }
{[question(21), option("10033-other")], }
{[question(22)], electric }

下面是我用来解决这个问题的代码片段:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var value = (Data)existingValue;
            if (value == null)
            {
                value = new Data();
                value.SurveyQuestions = new List<SurveyQuestion>();
                value.SurveyUrls = new List<SurveyUrl>();
                value.SurveyGeoDatas = new List<SurveyGeoData>();
                value.SurveyVariables = new List<SurveyVariable>();
                value.SurveyVariableShowns = new List<SurveyVariableShown>();
                value.SurveyQuestionHiddens = new List<SurveyQuestionHidden>();
                value.SurveyQuestionOptions = new List<SurveyQuestionOption>();
                value.SurveyQuestionMulties = new List<SurveyQuestionMulti>();
            }
            // Skip opening {
            reader.Read();
            while (reader.TokenType == JsonToken.PropertyName)
            {
                var name = reader.Value.ToString();
                reader.Read();
                // Here is where you do your magic
                string input = name;
                //[question(1)]
                //[question(11)]
                //[question(111)]
                //[question(1234)]
                //[question(12345)]
                //[url(12345)]
                //[variable(12345)]
                //SINGLE ANSWER
                Match matchSingleAnswer = Regex.Match(input, @"'[(question|calc|comment)'(([0-9]{5}|[0-9]{4}|[0-9]{3}|[0-9]{2}|[0-9]{1})')]",
                    RegexOptions.IgnoreCase);

                //SINGLE VARIABLE
                Match matchSingleVariable = Regex.Match(input, @"'[(variable)'(([0-9]{5}|[0-9]{4}|[0-9]{3}|[0-9]{2}|[0-9]{1})')]",
                    RegexOptions.IgnoreCase);
                //URL
                Match matchUrl = Regex.Match(input, @"'[url",
                    RegexOptions.IgnoreCase);
                //GEO DATA
                Match matchGeo = Regex.Match(input, @"'[variable'(""STANDARD_",
                    RegexOptions.IgnoreCase);
                //VARIABLES SHOWN
                Match matchVariables = Regex.Match(input, @"'[variable",
                    RegexOptions.IgnoreCase);
                //[question(1), option('"1
                //[question(11), option('"2
                //[question(111), option('"1
                //[question(1234), option('"1
                //[question(12345), option('"1
                ////////////////////////////////////////////
                ////////The ' values are being removed.
                ////////////////////////////////////////////
                //OPTIONAL ANSWERS
                string myReg = @"'[(question|url|variable|calc|comment)'(([0-9]{5}|[0-9]{4}|[0-9]{3}|[0-9]{2}|[0-9]{1})'),' option'(""[0-9]";
                Match matchOption = Regex.Match(input, myReg,
                    RegexOptions.IgnoreCase);
                //[question(1), option(1
                //[question(11), option(2
                //[question(111), option(1
                //[question(1234), option(1
                //[question(12345), option(1
                //MULTIPLE CHOICE
                Match matchMultiSelect = Regex.Match(input, @"'[question'(([0-9]{5}|[0-9]{4}|[0-9]{3}|[0-9]{2}|[0-9]{1})'),' option'([0-9]",
                    RegexOptions.IgnoreCase);

                //[question(1), option(0)
                //[question(11), option(0)
                //[question(111), option(0)
                //[question(1234), option(0)
                //[question(12345), option(0)
                //HIDDEN
                Match matchHiddenValue = Regex.Match(input, @"'[question'(([0-9]{5}|[0-9]{4}|[0-9]{3}|[0-9]{2}|[0-9]{1})'),' option'(0')",
                    RegexOptions.IgnoreCase);

                if (matchSingleAnswer.Success)
                {
                    int index = int.Parse(name.Substring(10, name.IndexOf(')') - 10));
                    SurveyQuestion sq = new SurveyQuestion();
                    sq.QuestionID = index;
                    sq.QuestionResponse = serializer.Deserialize<string>(reader);
                    value.SurveyQuestions.Add(sq);
                }
                else if (matchUrl.Success)
                {
                    string urlName = name.Substring(6, name.Length - 9);
                    SurveyUrl su = new SurveyUrl();
                    su.Name = urlName;
                    su.Value = serializer.Deserialize<string>(reader);
                    value.SurveyUrls.Add(su);
                }
                else if (matchGeo.Success)
                {
                    string geoName = name.Substring(11, name.Length - 14);
                    SurveyGeoData sgd = new SurveyGeoData();
                    sgd.Name = geoName;
                    sgd.Value = serializer.Deserialize<string>(reader);
                    value.SurveyGeoDatas.Add(sgd);
                }
                else if (matchSingleVariable.Success)
                {
                    int index = int.Parse(name.Substring(10, name.IndexOf(')') - 10));
                    SurveyVariable sv = new SurveyVariable();
                    sv.SurveyVariableID = index;
                    sv.Value = serializer.Deserialize<string>(reader);
                    value.SurveyVariables.Add(sv);
                }
                else if (matchVariables.Success)
                {
                    string varName = name.Substring(11, name.Length - 14);
                    SurveyVariableShown svs = new SurveyVariableShown();
                    svs.Name = varName;
                    svs.Value = serializer.Deserialize<string>(reader);
                    value.SurveyVariableShowns.Add(svs);
                }
                else if (matchHiddenValue.Success)
                {
                    int index = int.Parse(name.Substring(10, name.IndexOf(')') - 10));
                    SurveyQuestionHidden sqh = new SurveyQuestionHidden();
                    sqh.QuestionID = index;
                    sqh.QuestionResponse = serializer.Deserialize<string>(reader);
                    value.SurveyQuestionHiddens.Add(sqh);
                }
                else if (matchMultiSelect.Success)
                {
                    //Multiple choice question selections
                    string[] nameArray = name.Split(')');
                    string questionPart = nameArray[0];
                    string optionPart = nameArray[1];
                    int index = int.Parse(questionPart.Substring(10, questionPart.Length - 10));
                    int indexSub = int.Parse(optionPart.Substring(9, optionPart.Length - 9));
                    SurveyQuestionMulti sqm = new SurveyQuestionMulti();
                    sqm.OptionID = indexSub;
                    sqm.QuestionID = index;
                    sqm.QuestionResponse = serializer.Deserialize<string>(reader);
                    value.SurveyQuestionMulties.Add(sqm);
                    //NEED TO ADD A BASE QUESTION TO POINT TO ALL THE MULTI
                    //SurveyQuestion sq = new SurveyQuestion();
                    //sq.QuestionID = sqm.QuestionID;
                    //sq.QuestionResponse = "";
                    //value.SurveyQuestions.Add(sq);
                }
                else if (matchOption.Success)
                {
                    //Optional text value for a given question
                    string[] nameArray = name.Split(')');
                    string questionPart = nameArray[0];
                    string optionPart = nameArray[1];
                    int index = int.Parse(questionPart.Substring(10, questionPart.Length - 10));
                    int indexSub = int.Parse(optionPart.Substring(10, 5));
                    SurveyQuestionOption sqo = new SurveyQuestionOption();
                    sqo.OptionID = indexSub;
                    sqo.QuestionID = index;
                    sqo.QuestionResponse = serializer.Deserialize<string>(reader);
                    value.SurveyQuestionOptions.Add(sqo);
                }
                else
                {
                    var property = typeof(Data).GetProperty(name);
                    if (property != null)
                        property.SetValue(value, serializer.Deserialize(reader, property.PropertyType), null);
                }
                // Skip the , or } if we are at the end
                reader.Read();
            }
            return value;
        }