/// <summary> /// 根据类型和NodeID,获取具体的IConfigClassOfCustomHandler实例 /// </summary> /// <param name="ConfigClassType">类型,要求继承自IConfigClassOfCustomHandler</param> /// <param name="NodeId">节点ID</param> /// <returns>实例</returns> public static IConfigClassOfCustomHandler GetConfigClassInstance(Type ConfigClassType, string NodeId) { CheckClassType(ConfigClassType); //创建容器 IConfigClassOfCustomHandler DataInstance = Activator.CreateInstance(ConfigClassType) as IConfigClassOfCustomHandler; //读取数据 XDocument xdoc = LoadConfigByType(ConfigClassType); if (xdoc == null) { return(DataInstance); } XElement xeDataItem = xdoc.Root.Elements(DATA_ITEM) .Where(xe => xe.Attribute(NODE_ID).Value == NodeId) .FirstOrDefault(); //反序列化数据 if (xeDataItem != null) { DataInstance.DeserializeConfigFromXmlNode(xeDataItem); } //返回结果 return(DataInstance); }
/// <summary> /// 注入ConfigData /// </summary> /// <param name="Handler">标记为“参数可配置”的自定义处理器</param> /// <param name="ConfigData">参数配置实例</param> /// <returns>成功与否</returns> internal static bool ImportConfigData(ICustomHandlerConfigable Handler, IConfigClassOfCustomHandler ConfigData) { dynamic handler = Handler; handler.ConfigData = ConfigData; return(true); }
/// <summary> /// 根据类型和NodeID,获取具体的IConfigClassOfCustomHandler实例 /// </summary> /// <typeparam name="TConfigClass">类型,要求继承自IConfigClassOfCustomHandler</typeparam> /// <param name="NodeId">节点ID</param> /// <returns>实例</returns> public static TConfigClass GetConfigClassInstance <TConfigClass>(string NodeId) where TConfigClass : IConfigClassOfCustomHandler { //获取结果 Type targetType = typeof(TConfigClass); IConfigClassOfCustomHandler result = GetConfigClassInstance(targetType, NodeId); //空and非空 的处理 return(result == null ? default(TConfigClass) : (TConfigClass)result); }
/// <summary> /// 更新指定节点ID的配置(存在则修改,不存在则更新) /// </summary> /// <param name="xdoc">XDocument文档</param> /// <param name="NodeId">节点ID</param> /// <param name="config">IConfigClassOfCustomHandler对象</param> /// <returns>成功与否</returns> public static bool UpdateConfig(XDocument xdoc, string NodeId, IConfigClassOfCustomHandler config) { try { //检查是否存在 XElement xeTargetItem = xdoc.Root.Elements(DATA_ITEM) .Where(xe => xe.Attribute(NODE_ID).Value == NodeId) .FirstOrDefault(); if (xeTargetItem == null) { xeTargetItem = new XElement(DATA_ITEM); } xeTargetItem.SetAttributeValue(NODE_ID, NodeId); //重新赋值,防止序列化过程,某些实现不规范,将nodeID移除。 config.SerializeConfigToXmlNode(xeTargetItem); //序列化 xdoc.Root.Add(xeTargetItem); return(true); } catch (Exception) { return(false); } }
public ActionResult SaveEdit(Dictionary <string, string> parmDic) { /* Doubt: 只能序列化成 <Stirng,String>? 当使用<Stirng,dynamic>,无法为Value赋值"集合"/"JObject";会转换成无法使用的 System.Object? * * 因此这里的“DefaultNews”和 “TextMenu”, * 从View层序列化成 JsonString,然后再在Controller还原。 * 求解决方案。 */ //抽取基本数据 string targetNodeId = parmDic["NodeID"]; string NewNodeId = parmDic["NewNodeId"]; string DealingHandler = parmDic["DealingHandler"]; string DoneHandler = parmDic["DoneHandler"]; //检查ID是否重复、格式是否正确 if (targetNodeId != ConstString.ROOT_NODE_ID && targetNodeId != NewNodeId) //修改了NodeID时才检查 { if (NodeIdValidator.IsValid(NewNodeId) == false) { return(Json(new { IsSuccess = false, errorMessage = "節點ID格式不正確。必須為 x.y.z 序號格式。" })); } bool isExisted = false; lock (((ICollection)ConfigNodeList).SyncRoot) isExisted = ConfigNodeList.ContainsKey(NewNodeId); if (isExisted) { return(Json(new { IsSuccess = false, errorMessage = "修改的節點ID已經存在,不可以重複。" })); } } ResponseNodeConfig configNode = new ResponseNodeConfig(NewNodeId); StringBuilder errorMessage = new StringBuilder(); //开始根据不同类型,解析具体的数据 bool isNeedDoneHandler = true; //标记是否需要Done阶段;因为有部分Dealing处理器,处理完则跳转节点,此时不需要再配置Done。 #region DealingHandler switch (DealingHandler) { default: errorMessage.AppendLine("找不到對應的Dealing類型。"); break; case "DefaultText": { DefaultDealingHandlerConfig HandlerResult = new DefaultDealingHandlerConfig(); HandlerResult.DataType = DataTypes.Text; HandlerResult.RawData = parmDic["DealingHandler_DefaultText"]; configNode.DealingHandlerConfig = HandlerResult; } break; case "DefaultNews": { DefaultDealingHandlerConfig HandlerResult = new DefaultDealingHandlerConfig(); HandlerResult.DataType = DataTypes.News; dynamic news = Newtonsoft.Json.Linq.JObject.Parse(parmDic["DealingHandler_DefaultNews"]); HandlerResult.RawData = new ArticleCan(news.title.ToString(), news.description.ToString(), news.picUrl.ToString(), news.pageUrl.ToString()); configNode.DealingHandlerConfig = HandlerResult; } break; case "TextMenu": { TextMenuHandlerConfig HandlerResult = new TextMenuHandlerConfig(); //##提示文字 ResponseTextMessageConfig ready = new ResponseTextMessageConfig(); ready.Context = parmDic["DealingHandler_TextMenu_ReadyMessage"]; HandlerResult.ReadyMessageConfig = ready; //##菜单项 var menus = Newtonsoft.Json.Linq.JObject.Parse(parmDic["DealingHandler_TextMenu_Menus"]); foreach (var menu in menus) { string theNodeid = menu.Value["Id"].ToString().Replace("#", String.Empty); //??Json序列化时,如果Key为纯数字(即使类型是字符串),会被排序。因此这个用#前缀处理。 //有效性检查 if (NodeIdValidator.IsValid(theNodeid) == false) { errorMessage.Append(theNodeid); errorMessage.AppendLine("不是有效的節點ID格式。必須為 x.y.z 序號格式。"); break; } //重复检查(紧跟其下的目标跳转的节点ID,不能与当前节点ID一样,否则会直接循环跳转 ; 跨节点的,不限制。) if (String.Equals(NewNodeId, theNodeid, StringComparison.OrdinalIgnoreCase)) { errorMessage.Append("子節點"); errorMessage.Append(theNodeid); errorMessage.AppendLine(",不能與當前節點的ID重複。"); break; } HandlerResult.Menus.Add(new DictionaryEntry(menu.Value["data"].ToString(), theNodeid)); } configNode.DealingHandlerConfig = HandlerResult; isNeedDoneHandler = false; //标记不处理Done } break; case "CustomHandler": { CustomHandlerConfig HandlerResult = new CustomHandlerConfig(); HandlerResult.HandlerTypeName = parmDic["DealingHandler_CustomHandler"]; configNode.DealingHandlerConfig = HandlerResult; //自定义处理的参数配置 Type targetType = CustomHandlerConfig.GetICustomHandlerTypeFromCurrentDomain(HandlerResult.HandlerTypeName); bool isConfigable = typeof(ICustomHandlerConfigable).IsAssignableFrom(targetType); if (isConfigable && Session["AdvantanceConfig_CustomHandler_Result"] != null) { var dictionary = Session["AdvantanceConfig_CustomHandler_Result"] as IDictionary <Type, IConfigClassOfCustomHandler>; if (dictionary != null && dictionary.ContainsKey(targetType)) { IConfigClassOfCustomHandler configData = dictionary[targetType] as IConfigClassOfCustomHandler; if (configData != null) { //获取配置类 Type configClassType = ConfigClassOfCustomHandlerHelper.GetConfigClassType(targetType); if (configClassType != null) { //加载 XDocument xdoc = ConfigClassOfCustomHandlerHelper.LoadConfigByType(configClassType); ConfigClassOfCustomHandlerHelper.RemoveConfig(xdoc, targetNodeId); ConfigClassOfCustomHandlerHelper.UpdateConfig(xdoc, NewNodeId, configData); //保存 ConfigClassOfCustomHandlerHelper.SaveConfigByType(configClassType, xdoc); } } } } } break; } #endregion #region DoneHandler if (isNeedDoneHandler) { switch (DoneHandler) { default: errorMessage.AppendLine("找不到對應的Done類型。"); break; case "DefaultRootNode": { //DefaultDoneHandlerConfig HandlerResult = new DefaultDoneHandlerConfig(); configNode.DoneHandlerConfig = null; } break; case "DefaultTargetNode": { if (NodeIdValidator.IsValid(parmDic["DoneHandler_JumpNode"]) == false) { errorMessage.Append(parmDic["DoneHandler_JumpNode"]); errorMessage.AppendLine("不是有效的節點ID格式。必須為 x.y.z 序號格式。"); break; } DefaultDoneHandlerConfig HandlerResult = new DefaultDoneHandlerConfig(); HandlerResult.NodeId = parmDic["DoneHandler_JumpNode"]; HandlerResult.TipText = parmDic["DoneHandler_TipText"]; configNode.DoneHandlerConfig = HandlerResult; } break; } } #endregion //反馈结果 if (errorMessage.Length <= 0) { SaveOneConfig(configNode, targetNodeId); return(Json(new { IsSuccess = true })); } else { return(Json(new { IsSuccess = false, errorMessage = errorMessage.ToString() })); } }