在混合开发框架模式中,有时候我们在处理树形节点的时候,需要很多关联的处理,可能需要结合用户配置信息,属性字典,以及表的字段分类等信息来展示一个结构树,那么在处理的时候就可能会频繁的对这些接口API进行调用,而如果我们使用Web API一次性的获取树形节点信息,然后统一加载的话,性能会提升很多,本篇随笔介绍通过封装一个总的树形结构列表数据返回的Web API,从而在Winform客户端一次性展示的方式,实现性能的优化处理。

1、树形结构展示效果

如下面的CRM客户关系管理系统中,我们需要展示很多客户相关的树形节点,以方便快捷查询相关类型的客户信息。

那么这个树列表就需要结合很多属性来处理了,包括了客户的字段信息,客户配置显示信息,每个字段类型的对应的字典信息,如客户状态、客户类型等等。

因此如果在客户端整合逻辑,那么需要对几个不同的处理接口进行调用并处理,这种解析起来比较慢,而且也会导致处理效率问题。

一般情况下,我们云端的服务器性能会比客户端的性能更好一些,这些对数据库处理的逻辑封装在Web API的后盾会更加方便,也就是瘦客户端的方式更有效率了。

2、Web API端封装处理逻辑

例如我们定义一个以下的接口来获取数据。

  1. /// <summary>
  2. /// 获取客户树形类别的数据
  3. /// </summary>
  4. /// <param name="userId">当前用户ID</param>
  5. /// <param name="companyId">所属公司ID</param>
  6. /// <param name="dataFilter">数据过滤条件</param>
  7. /// <param name="shareUserCondition">分配用户ID条件</param>
  8. /// <returns></returns>
  9. List<TreeNodeInfo> GetCustomerTree(string userId, string companyId, string dataFilter, string shareUserCondition);

其中TreeNodeInfo对象是我们自己定义的一个对象,用来承载具有层级信息的列表信息。

具体这个类的代码如下所示。

  1. /// <summary>
  2. /// 用来承载TreeNode的信息
  3. /// </summary>
  4. [Serializable]
  5. [DataContract]
  6. public class TreeNodeInfo
  7. {
  8. /// <summary>
  9. /// 子对象集合
  10. /// </summary>
  11. [DataMember]
  12. public List<TreeNodeInfo> Nodes { get; set; }
  13.  
  14. /// <summary>
  15. /// 节点名称
  16. /// </summary>
  17. [DataMember]
  18. public string Text { get; set; }
  19.  
  20. /// <summary>
  21. /// 节点标签
  22. /// </summary>
  23. [DataMember]
  24. public string Tag { get; set; }
  25.  
  26. /// <summary>
  27. /// 图标序号
  28. /// </summary>
  29. [DataMember]
  30. public int IconIndex { get; set; }
  31.  
  32. /// <summary>
  33. /// 是否展开
  34. /// </summary>
  35. [DataMember]
  36. public bool IsExpanded { get; set; }
  37.  
  38. /// <summary>
  39. /// 前景色
  40. /// </summary>
  41. [DataMember]
  42. public string ForeColor { get; set; }
  43.  
  44. /// <summary>
  45. /// 默认构造函数
  46. /// </summary>
  47. public TreeNodeInfo() {
  48. this.Nodes = new List<TreeNodeInfo>();
  49. }
  50.  
  51. /// <summary>
  52. /// 参数构造函数
  53. /// </summary>
  54. /// <param name="text">节点名称</param>
  55. /// <param name="iconIndex">图标序号</param>
  56. /// <param name="tag">节点标签</param>
  57. public TreeNodeInfo(string text, int iconIndex, string tag = "") : this()
  58. {
  59. this.Text = text;
  60. this.IconIndex = iconIndex;
  61. this.Tag = tag;
  62. }
  63. }

Web API端的控制器方法如下所示。

最后具体在客户端界面绑定显示数据的逻辑如下所示。

  1. /// <summary>
  2. /// 使用Json对象创建列表树
  3. /// </summary>
  4. private void InitTree()
  5. {
  6. //清空节点信息
  7. this.treeView1.Nodes.Clear();
  8.  
  9. //通过Web API方式获取树对象列表结构
  10. var list = CallerFactory<ICustomerService>.Instance.GetCustomerTree(LoginUserInfo.ID, this.SelectedCompanyID,
  11. this.DataFilterCondition, this.ShareUserCondition);
  12.  
  13. if (list != null && list.Count > )
  14. {
  15. //遍历每个节点,生成对应的TreeView对象节点
  16. foreach (var node in list)
  17. {
  18. //构建TreeView对象节点信息
  19. TreeNode parentNode = new TreeNode(node.Text, node.IconIndex, node.IconIndex);
  20. parentNode.Tag = node.Tag;
  21. if (!string.IsNullOrEmpty(node.ForeColor))
  22. {
  23. //如果节点颜色有值,则修改前景色
  24. parentNode.ForeColor = ColorTranslator.FromHtml(node.ForeColor);
  25. }
  26.  
  27. //递归处理树形列表
  28. InitTreeNode(node.Nodes, parentNode);
  29. if (parentNode.Text != "标记颜色")
  30. {
  31. parentNode.Expand();//选择性的展开部分一级节点
  32. }
  33.  
  34. //把根节点加入到树对象里面显示
  35. this.treeView1.Nodes.Add(parentNode);
  36. }
  37. }
  38. }
  39.  
  40. /// <summary>
  41. /// 递归处理树形列表
  42. /// </summary>
  43. /// <param name="nodes">树节点信息对象</param>
  44. /// <param name="pNode">TreeView根节点</param>
  45. private void InitTreeNode(List<TreeNodeInfo> nodes, TreeNode pNode)
  46. {
  47. foreach (TreeNodeInfo node in nodes)
  48. {
  49. TreeNode subNode = new TreeNode(node.Text, node.IconIndex, node.IconIndex);
  50. subNode.Tag = node.Tag;
  51. if (!string.IsNullOrEmpty(node.ForeColor))
  52. {
  53. //如果节点颜色有值,则修改前景色
  54. subNode.ForeColor = ColorTranslator.FromHtml(node.ForeColor);
  55. }
  56.  
  57. //递归调用
  58. InitTreeNode(node.Nodes, subNode);
  59. pNode.Nodes.Add(subNode);
  60. }
  61. }

这里基本不会涉及很多逻辑,我们只需要对树形节点的结构进行遍历展示即可。

其实后端已经给我们处理好很多数据了,包括对节点构建、数据字典的处理,以及每个条件的数量处理都合并一起,它的逻辑还是很多的。

这个部分的逻辑由于代码量比较大,我们可以简化抽取出来一个辅助类处理,这样在需要的地方直接调用辅助类进行处理就可以了。

抽取辅助类后,对处理逻辑的调用简单了很多。

  1. CustomerHelper helper = new CustomerHelper();
  2. var result = helper.GetCustomerTree(userId, companyId, dataFilter, shareUserCondition);

这部分有300多行代码,具体就不再一一介绍了,主要就是对各个接口的处理,获取数据并组装起来。

这种在服务器端对主要逻辑进行封装,简化客户端的处理逻辑,是我们推荐的方式,可以极大的提高界面响应效率,减少不必要的网络延迟损耗,从而提高用户的体验效果,对于具有较高运算速度的服务器,更是物尽其用。

在混合开发框架模式中,简化客户端对Web API的频繁调用的更多相关文章

  1. Identity Server 4 从入门到落地(十)—— 编写可配置的客户端和Web Api

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  2. [水煮 ASP.NET Web API2 方法论](1-1)在MVC 应用程序中添加 ASP.NET Web API

    问题 怎么样将 Asp.Net Web Api 加入到现有的 Asp.Net MVC 项目中 解决方案 在 Visual Studio 2012 中就已经把 Asp.Net Web Api 自动地整合 ...

  3. [水煮 ASP.NET Web API2 方法论](1-2)在 WebForm 应用程序中添加 ASP.NET Web API

    问题 怎么样将 Asp.Net Web Api 加入到 Asp.Net Web From 应用程序中 解决方案 在 Visual Studio 2013 中,创建新的 Web From,可以直接在&q ...

  4. 尝新体验ASP.NET Core 6预览版本中发布的最小Web API(minimal APIS)新特性

    本文首发于<尝新体验ASP.NET Core 6预览版本中发布的最小Web API(minimal APIS)新特性> 概述 .NET开发者们大家好,我是Rector. 几天前(美国时间2 ...

  5. 【Azure API 管理】在APIM中使用客户端证书验证API的请求,但是一直提示错误"No client certificate received."

    API 管理 (APIM) 是一种为现有后端服务创建一致且现代化的 API 网关的方法. 问题描述 在设置了APIM客户端证书,用户保护后端API,让请求更安全. 但是,最近发现使用客户端证书的API ...

  6. Self Host模式下的ASP. NET Web API是如何进行请求的监听与处理的?

    构成ASP.NET Web API核心框架的消息处理管道既不关心请求消息来源于何处,也不需要考虑响应消息归于何方.当我们采用Web Host模式将一个ASP.NET应用作为目标Web API的宿主时, ...

  7. 简单记录在Visual Studio 2013中创建ASP.NET Web API 2

    在很多跨平台的应用中就需要Web API ,比如android与数据库的交互. Create a Web API Project 选择新建项目下的模板下的Visual C#节点下的Web节点,在模板列 ...

  8. 在Docker容器中运行.Net Core web Api项目

    安装Docker环境 参考本人这篇<CentOS 7 下Docker的安装>文章进行安装以及环境配置,这里不做赘述. 通过.NetCore开发WebApi项目 1. 创建.Net Core ...

  9. ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用

    在前面几篇随笔介绍了我对ABP框架的改造,包括对ABP总体的介绍,以及对各个业务分层的简化,Web API 客户端封装层的设计,使得我们基于ABP框架的整体方案越来越清晰化, 也越来越接近实际的项目开 ...

随机推荐

  1. 吴恩达机器学习笔记58-协同过滤算法(Collaborative Filtering Algorithm)

    在之前的基于内容的推荐系统中,对于每一部电影,我们都掌握了可用的特征,使用这些特征训练出了每一个用户的参数.相反地,如果我们拥有用户的参数,我们可以学习得出电影的特征. 但是如果我们既没有用户的参数, ...

  2. PHP全栈学习笔记16

    <?php $fileName = "php大师.test.php"; //补充程序,显示文件名(不包括扩展名) $start = strrpos($fileName, &q ...

  3. AI - TensorFlow - 第一个神经网络(First Neural Network)

    Hello world # coding=utf-8 import tensorflow as tf import os os.environ[' try: tf.contrib.eager.enab ...

  4. KeyboardUtil【软键盘弹出后输入框上移一定的高度】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 演示获取软键盘高度并保存,然后根据输入框的原有位置是否被软键盘挡住了,如果被挡住了则将整体页面上移一定的高度,当软键盘隐藏的时候再下 ...

  5. Android中EditText显示明文与密文的两种方式

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 记录输入框显示.隐藏密码的简单布局以及实现方式. 效果图    代码分析 方式一 /**方式一:*/ private void sh ...

  6. c++智能指针和二叉树(1): 图解层序遍历和逐层打印二叉树

    二叉树是极为常见的数据结构,关于如何遍历其中元素的文章更是数不胜数. 然而大多数文章都是讲解的前序/中序/后序遍历,有关逐层打印元素的文章并不多,已有文章的讲解也较为晦涩读起来不得要领.本文将用形象的 ...

  7. Redis集群伸缩

    集群扩容 前提准备,目前集群中一共有6台机器,端口号分别是6381.6382.6383.6384.6385.6386 1) 准备新节点 准备两个新节点,端口号为6387和6388,配置和以前集群配置一 ...

  8. [翻译] 使用 Python 创建你自己的 Shell:Part II

    目录 使用 Python 创建你自己的 Shell:Part II 原文链接与说明 步骤 4:内置命令 最后的想法 使用 Python 创建你自己的 Shell:Part II 原文链接与说明 htt ...

  9. .Net Core 根据配置文件动态发布至服务器

    前言 一个软件的开发周期需要经历开发.测试.上线三个基本的阶段,同理我们在开发过程中会需要经常切换不同的运行环境..NetCore可以通过配置文件以及写入系统环境变量来自动识别站点的运行环境,保证了数 ...

  10. TensorFlow实现XOR

    TensorFlow基础 1.概念 TF使用图表示计算任务,图包括数据(Data).流(Flow).图(Graph) 图中节点称为op,一个op获得多个Tensor Tensor为张量,TF中用到的数 ...