前言:
在.NET种,序列化一般常用的方式是使用Newtonsoft.Json进行序列化和反序列化操作,比如创建一个Person类
public class Person
{public string Name { get; set; }public int Age { get; set; }
}
序列化为json
// 对象序列化为 JSONPerson 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;//判断是否为objectbool 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>();}//添加一个ObjectConfigPublishVariableInfo 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);}