当名称有括号和圆括号时反序列化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:
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;
}