C#解析JSON动态对象及遍历处理业务规则技术咨询
拧紧结果数据的JSON遍历与业务规则实现
我需要处理一段包含拧紧结果元数据的JSON字符串,核心需求是遍历并提取其中的属性信息,区分Header和DataFields两种类型,同时实现一套可快速查询的仓储机制,适配业务规则验证的需求。
目标JSON结构
首先是需要处理的JSON字符串:
string jsonobj = "[{'LastTighteningResultDataRev3': 'Header', 'Attribute': ['Length','1','4']}, {'LastTighteningResultDataRev3': 'Header', 'Attribute': ['MID','5','4']}, {'LastTighteningResultDataRev3': 'Header', 'Attribute': ['REV','9','3']}, {'LastTighteningResultDataRev3': 'DataFields', 'Attribute': ['CellID','21','2','23','3']}, {'LastTighteningResultDataRev3': 'DataFields', 'Attribute': ['ChannelID','27','2','29','2']}]";
JSON反序列化实现
我采用匿名类型进行反序列化,确保能精准匹配JSON的结构:
#region "Parse Data Schema" var tempObj = new[] { new { LastTighteningResultDataRev3 = "", Attribute = new List<string>() } }; var deserializedObject = JsonConvert.DeserializeAnonymousType(jsonobj, tempObj); #endregion
最终采用的遍历处理代码
这段代码会遍历所有反序列化后的对象,区分Header和DataFields类型,提取对应的属性位置、长度信息,并从测试响应中截取实际值,最后加载到仓储中:
#region "LoadACOPLastTighteningResultDataGLRepository using the Data Schema Information" deserializedObject.ToList().ForEach(attrs => { #region "InitACOPLastTighteningResultDataProperties" acoplasttighteningresultdatacs.InitACOPLastTighteningResultDataProperties(); #endregion #region "Load Attribute Parse Information from Data Schema Information" acoplasttighteningresultdatacs.p_Attribute = attrs.Attribute[0]; acoplasttighteningresultdatacs.p_AttributeIDStartPosition = attrs.Attribute[1]; acoplasttighteningresultdatacs.p_AttributeIDLength = attrs.Attribute[2]; if (attrs.LastTighteningResultDataRev3 == "DataFields") acoplasttighteningresultdatacs.p_AttributeValueStartPosition = attrs.Attribute[3]; if (attrs.LastTighteningResultDataRev3 == "DataFields") acoplasttighteningresultdatacs.p_AttributeValueStartLength = attrs.Attribute[4]; #region "Load attribute ID values from controller response mesage" acoplasttighteningresultdatacs.p_AttributeIDValue = (attrs.LastTighteningResultDataRev3 == "DataFields") ? testrequestresponseinfocs.p_TestResult.Substring(Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeIDStartPosition) - 1, Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeIDLength)) : null; #endregion #region "Load attribute values from controller response mesage" if (attrs.LastTighteningResultDataRev3 == "Header") acoplasttighteningresultdatacs.p_AttributeValue = testrequestresponseinfocs.p_TestResult.Substring(Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeIDStartPosition) - 1, Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeIDLength)); if (attrs.LastTighteningResultDataRev3 == "DataFields") acoplasttighteningresultdatacs.p_AttributeValue = testrequestresponseinfocs.p_TestResult.Substring(Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeValueStartPosition) - 1, Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeValueStartLength)); #endregion #endregion if (acoplasttighteningresultdatacs.LoadACOPLastTighteningResultDataGLRepository()) return; }); #endregion
备用的筛选DataFields代码
如果只需要处理DataFields类型的数据,这段代码可以直接筛选后处理:
var deserializedList = JsonConvert.DeserializeAnonymousType(LastTighteningResultDT.Rows[0]["DataSchema"].ToString(), tempObj).ToList(); deserializedList.Where(x => x.LastTighteningResultDataRev3 =="DataFields").Select(y => y.Attribute).ToList().ForEach(attrs => { { acoplasttighteningresultdatacs.p_Attribute = attrs[0]; acoplasttighteningresultdatacs.p_AttributeIDStartPosition = attrs[1]; acoplasttighteningresultdatacs.p_AttributeIDLength = attrs[2]; #region "Load attribute values from controller response mesage" acoplasttighteningresultdatacs.p_AttributeIDValue = testrequestresponseinfocs.p_TestResult.Substring(Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeIDStartPosition) - 1, Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeIDLength)); #endregion acoplasttighteningresultdatacs.p_AttributeValueStartPosition = attrs[3]; acoplasttighteningresultdatacs.p_AttributeValueStartLength = attrs[4]; #region "Load attribute values from controller response mesage" acoplasttighteningresultdatacs.p_AttributeValue = testrequestresponseinfocs.p_TestResult.Substring(Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeValueStartPosition) - 1, Convert.ToInt16(acoplasttighteningresultdatacs.p_AttributeValueStartLength)); #endregion if (acoplasttighteningresultdatacs.LoadACOPLastTighteningResultDataGLRepository()) return; } });
仓储与字典实现(支持业务规则快速查询)
为了适配业务规则验证的需求,我实现了静态字典和列表,用来存储拧紧结果数据,这样即使Schema变更,也能快速查询到目标属性(比如TighteningStatus):
#region "Static ACOPLastTighteningResultDataCS Dictionary" public static Dictionary<int, ACOPLastTighteningResultDataCS> ACOPLastTighteningResultDataDictionary = new Dictionary<int, ACOPLastTighteningResultDataCS>(); #endregion #region "Static ACOPLastTighteningResultDataRepositoryForAttribute" public static List<ACOPLastTighteningResultDataCS> ACOPLastTighteningResultDataRepositoryForAttribute = new List<ACOPLastTighteningResultDataCS>(); #endregion
业务规则验证逻辑
根据不同的业务规则类型(长度检查、包含、比较、有效范围、授权),实现对应的验证逻辑,其中Compare类型会从字典中查询属性值进行验证:
#region "Validate by Business Rule Type" bool ValidatedSW = false; switch (Convert.ToInt32(BusinessRuleInfoDT.Rows[0]["BusinessRuleTypeInfoID"].ToString())) { case ((int)BusinessRuleTypes.Length): { if (gvTestActions.Rows[gvTestActions.CurrentRow.Index].Cells[(int)gvCols.ScannedInValue].Value.ToString().Trim().Length == Convert.ToInt32(BusinessRuleInfoDT.Rows[0]["Value"])) ValidatedSW = true; break; } case ((int)BusinessRuleTypes.Contains): { ValidatedSW = false; break; } case ((int)BusinessRuleTypes.Compare): { if (!(ACOPLastTighteningResultDataCS.LoadACOPLastTighteningResultDataDictionary())) break; if (!(ACOPLastTighteningResultDataCS.GetACOPLastTighteningResultDataByAttributeID(Convert.ToInt32(BusinessRuleInfoDT.Rows[0]["AttributeID"])))) return; if (Convert.ToInt32(ACOPLastTighteningResultDataCS.ACOPLastTighteningResultDataRepositoryForAttribute[0].p_AttributeValue) == Convert.ToInt32(BusinessRuleInfoDT.Rows[0]["Value"])) ValidatedSW = true; break; } case ((int)BusinessRuleTypes.ValidRange): { ValidatedSW = false; break; } case ((int)BusinessRuleTypes.Authorize): { ValidatedSW = false; break; } } #endregion
字典加载方法
从泛型仓储列表中加载数据到字典,以AttributeIDValue为键,方便快速查询:
#region "LoadACOPLastTighteningResultDataDictionary" public static bool LoadACOPLastTighteningResultDataDictionary() { try { #region "Clear dictionary" if (ACOPLastTighteningResultDataDictionary.Count > 0) ACOPLastTighteningResultDataDictionary.Clear(); #endregion #region "Load dictionary from generic list class" ACOPLastTighteningResultDataDictionary = ACOPLastTighteningResultDataGLRepository.Where(x => x.p_AttributeIDValue != null).ToDictionary(p => Convert.ToInt32(p.p_AttributeIDValue), p => p); #endregion return true; } catch (Exception ex) { return false; } } #endregion
属性查询方法
根据AttributeID从字典中查询数据,并加载到静态列表中,方便UI线程访问:
#region "GetACOPLastTighteningResultDataByAttributeID" public static bool GetACOPLastTighteningResultDataByAttributeID(int AttributeID) { try { ACOPLastTighteningResultDataCS acopLastTighteningResultDataGLRepository; if (!(ACOPLastTighteningResultDataDictionary.TryGetValue(AttributeID, out acopLastTighteningResultDataGLRepository))) return false; ACOPLastTighteningResultDataRepositoryForAttribute.Add(new ACOPLastTighteningResultDataCS { p_AttributeIDStartPosition = acopLastTighteningResultDataGLRepository.p_AttributeIDStartPosition, p_AttributeIDLength = acopLastTighteningResultDataGLRepository.p_AttributeIDLength, p_Attribute = acopLastTighteningResultDataGLRepository.p_Attribute, p_AttributeIDValue = acopLastTighteningResultDataGLRepository.p_AttributeIDValue, p_AttributeValue = acopLastTighteningResultDataGLRepository.p_AttributeValue, p_AttributeValueStartPosition = acopLastTighteningResultDataGLRepository.p_AttributeValueStartPosition, p_AttributeValueStartLength = acopLastTighteningResultDataGLRepository.p_AttributeValueStartLength }); return true; } catch (Exception ex) { return false; } } #endregion
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

