前言:
在.NET种,序列化一般常用的方式是使用Newtonsoft.Json进行序列化和反序列化操作,比如创建一个Person类
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
序列化为json
// 对象序列化为 JSON
Person person = new Person { Name = "张三李四", Age = 25 };
string json = JsonConvert.SerializeObject(person);
Console.WriteLine(json);
得到的json如下
{"Name":"Alice","Age":25}
反序列化
Person deserializedPerson = JsonConvert.DeserializeObject<Person>(json);
以上方法是我们经常用的方法,但是现实中总有奇葩(跟我一起读:sha bi)的需求,以上序列化方式,是将Person的name序列化为json的key(name),将值序列化为json的值(Alice),但是如果有奇葩的需求,是反过来的,我们应该如何处理?
怎么处理?能怎么处理?还不得找办法解决
正文
创建一个公用的类,用于构造数据
public class JsonData
{
public PublishSubscribJsonData()
{
JsonDatas= new List<JsonData>();
}
public string MQTTName { get; set; }
public JsonDataTypeAttData{ get; set; }
public List<JsonData> JsonDatas{ get; set; }
}
public enum AttributeDataType
{
Int,
String,
Boolean,
Array,
Object
}
序列化
private static string ModelListToJson(List<JsonData> data)
{
StringBuilder sb = new StringBuilder();
sb.Append("{");
int index = 0;
foreach (var item in data)
{
if (index > 0)
{
sb.Append(",");
}
switch (item.AttData )
{
case JsonDataType.Int:
sb.Append($"\"{item.Name }\":0");
break;
case JsonDataType.String:
sb.Append($"\"{item.Name}\":\"\"");
break;
case JsonDataType.Boolean:
sb.Append($"\"{item.Name}\":\"false\"");
break;
case JsonDataType.Array:
sb.Append($"\"{item.Name}\":");
sb.Append("[");
//这里数据特殊,需要额外处理
int indexArr = 0;
//判断是否为object
bool obj = false;
if (item.JsonDatas .Count==1)
{
if (item.JsonDatas.FirstOrDefault().AttData == JsonDataType.Object)
{
obj = true;
foreach (var itemArr in item.JsonDatas)
{
if (indexArr > 0)
{
sb.Append(",");
}
//sb.Append($"\"{itemArr.Name}\":");
sb.Append(ModelListToJson(itemArr.JsonDatas));
indexArr++;
}
}
}
if (!obj)
{
sb.Append(ModelListToJson(item.JsonDatas));
}
sb.Append("]");
break;
case JsonDataType.Object:
sb.Append($"\"{item.Name}\":");
sb.Append(ModelListToJson(item.JsonDatas));
break;
default:
break;
}
index++;
}
sb.Append("}");
return sb.ToString();
}
反序列化
JObject data = JObject.Parse(jsonCionfig);
foreach (var property in data.Properties())
{
ConfigPublishVariableInfo configPublishVariableInfo = ConfigPublishVariableInfo.CreateAsChild();
configPublishVariableInfo.Id = Guid.NewGuid();
configPublishVariableInfo.MQTTName = property.Name;
configPublishVariableInfo.ConnId = ConnId;
ConfigPublishVariableInfo configPublishVariable = GetConfigPublishVariable(Model.ConfigPublishVariableData, configPublishVariableInfo.MQTTName);
if (CombinationTypes.Any())
{
configPublishVariableInfo.BinationTypeId = CombinationTypes.FirstOrDefault().Id;
}
JToken jToken = property.Value;
switch (jToken.Type)
{
case JTokenType.None:
case JTokenType.Property:
case JTokenType.Constructor:
case JTokenType.String:
case JTokenType.TimeSpan:
case JTokenType.Uri:
case JTokenType.Guid:
case JTokenType.Null:
case JTokenType.Undefined:
case JTokenType.Date:
case JTokenType.Raw:
case JTokenType.Bytes:
configPublishVariableInfo.AttributeData = AttributeDataType.String;
configPublishVariableInfo.DefaultValue = "";
break;
case JTokenType.Object:
configPublishVariableInfo.AttributeData = AttributeDataType.Object;
JObject objData = JObject.Parse(jToken.ToString());
ParseJObject(objData, configPublishVariableInfo);
break;
case JTokenType.Array:
configPublishVariableInfo.AttributeData = AttributeDataType.Array;
if (configPublishVariableInfo.ConfigPublishArrarData == null || configPublishVariableInfo.ConfigPublishArrarData.Count < 0)
{
configPublishVariableInfo.ConfigPublishArrarData = new ObservableCollection<ConfigPublishVariableInfo>();
}
//添加一个Object
ConfigPublishVariableInfo ObjectInfo = ConfigPublishVariableInfo.CreateAsChild();
ObjectInfo.Id = Guid.NewGuid();
ObjectInfo.ConnId = ConnId;
if (CombinationTypes.Any())
{
ObjectInfo.BinationTypeId = CombinationTypes.FirstOrDefault().Id;
}
ObjectInfo.MQTTName = configPublishVariableInfo.MQTTName + $"_{0}";
ObjectInfo.AttributeData = AttributeDataType.Object;
ObjectInfo.ConfigPublishArrarData = new ObservableCollection<ConfigPublishVariableInfo>();
for (int i = 0; i < jToken.Children().Count(); i++)
{
JObject objDatas = JObject.Parse(jToken[i].ToString());
ParseJObject(objDatas, ObjectInfo);
}
configPublishVariableInfo.ConfigPublishArrarData.Add(ObjectInfo);
break;
case JTokenType.Comment:
break;
case JTokenType.Integer:
configPublishVariableInfo.AttributeData = AttributeDataType.Int;
configPublishVariableInfo.DefaultValue = "0";
break;
case JTokenType.Float:
configPublishVariableInfo.AttributeData = AttributeDataType.Float;
configPublishVariableInfo.DefaultValue = "0.1";
break;
case JTokenType.Boolean:
configPublishVariableInfo.AttributeData = AttributeDataType.Boolean;
configPublishVariableInfo.DefaultValue = false.ToString();
break;
default:
break;
}
ConfigPublishVariableData.Add(configPublishVariableInfo);
}