前言

框架中HTTP网络请求使用了微软公司开发的 System.Net.Http.HttpClient 组件。

System.Net.Http.HttpClient 是微软推出的最新的 HTTP 应用程序的编程接口,微软称之为“现代化的 HTTP 编程接口”,命名空间 System.Net.Http 以及 System.Net.Http.Headers 提供了如下内容:

  1. HttpClient 发送和接收 HTTP 请求与响应;
  2. HttpRequestMessage 和 HttpResponseMessage 封装了 RFC 2616 定义的 HTTP 消息;
  3. HttpHeaders 封装了 RFC 2616 定义的 HTTP 标头;
  4. HttpClientHandler 负责生成HTTP响应消息的HTTP处理程序。

组件介绍

框架中的 XCI.Core.WebApi 组件对 HttpClient 组件进行了适当的封装,以方便接口调用以及数据提交。

WebApi 组件功能上对文件的上传和下载进行了单独的封装,用起来更加简便。从请求方法上分为:GETPOST,每种请求方法从返回值又分为:返回字符串返回通用消息对象返回泛型消息对象。而POST方法从提交数据上分为:提交键值对数据提交JSON字符串数据

最佳实践:推荐的使用方**式是WebApi组**件针对一个服务器只需要创建一个实例,即单例模式,每个方法都是线程安全的,并不需要创建多个WebApi实例。

预定义规则

组件中的每个方法都有两个共同的参数:接口请求地址(url)、提交的数据(data)。针对这两个参数有预定义规则。

接口请求地址

接口请求地址由两部分组成:基地址和接口地址两部分组成。例如:http://localhost:6070/api/sys/system/ping,其中基地址是http://localhost:6070,接口地址是`/api/sys/system/ping`。而通常情况下,我们调用的绝大多数接口的基地址是一样的,所以我们调用的时候只需要传递接口地址,而基地址在组件初始化的时候通过构造函数传入即可。如果部分接口的基地址不一致,我们可以传入完整的接口请求地址,比如:`http://www.icoc.group/api/sys/system/name`,由于传入的地址是一个完整的http地址,所以此时会忽略构造函数中传递的基地址。

  1. //构建通讯对象
  2. WebApi api = new WebApi("http://localhost:6070", TimeSpan.FromSeconds(10), false);
  3. api.Get("/api/sys/system/ping");//正确
  4. api.Get("api/sys/system/ping");//正确
  5. api.Get("http://localhost:6070/api/sys/system/ping");//正确
  6. api.Get("http://www.icoc.group/api/sys/system/name");//正确

最佳实践:推荐的使用方式是在构造函数中传递服务基地址,在接口调用时只写接口地址,并且接口地址以 **/** 开头。

提交的数据

在每个函数中都有一个data参数,所有的data参数都是可选项,data参数是object,目前支持的类型:

  1. 实现了接口 IDictionary<string,object> 的集合对象。
  2. 普通C#类,通过反射机制,读取实例的属性和属性值放入一个字典集合中,其中属性名称作为字典键,属性值作为字典值。
  3. 如果以JSON方式提交的话会把data参数序列化为字符串提交。

构造函数

构造函数中主要有三个参数:

  1. baseUrl 字符串类型,指定服务基地址,例如:http://localhost:6070
  2. timeout 时间间隔类型,指定请求超时间隔,例如:TimeSpan.FromSeconds(10) 10秒
  3. bool useProxy 布尔类型,指定是否使用代理,如果要使用调试工具,必须设置为true,发布时设置为false,可以加快接口调用。

也有其他重载的构造函数,也可以在对象创建完成后,通过实例方法单独设置参数

  • SetBaseUrl 设置服务基地址
  • SetTimeout 设置请求超时间隔

GET方法

  1. //从返回值分为:返回字符串、返回通用消息对象、返回泛型消息对象
  2. public string Get(string url, object data = null) //Get请求返回字符串
  3. public BoolMessage<T> Get<T>(string url, object data = null) //Get请求返回泛型消息对象
  4. public BoolMessage GetAsMessage(string url, object data = null) //Get请求返回通用消息对象

POST方法

从提交数据上分为:提交键值对数据提交JSON字符串数据

1. 提交键值对数据

  1. //从返回值分为:返回字符串、返回通用消息对象、返回泛型消息对象
  2. public string Post(string url, object data = null) //Post请求返回字符串
  3. public BoolMessage<T> Post<T>(string url, object data = null) //Post请求返回泛型消息对象
  4. public BoolMessage PostAsMessage(string url, object data = null) //Post请求返回通用消息对象

2. 提交JSON字符串数据

  1. //从返回值分为:返回字符串、返回通用消息对象、返回泛型消息对象
  2. public string PostJson(string url, object data = null) //Json方式Post请求返回字符串
  3. public BoolMessage<T> PostJson<T>(string url, object data = null) //Json方式Post请求返回泛型消息对象
  4. public BoolMessage PostJsonAsMessage(string url, object data = null) //Json方式Post请求返回通用消息对象

文件上传

文件上传全部使用POST方法。

  1. //从返回值分为:返回字符串、返回泛型消息对象泛型对象类型:FileModel
  2. //从上传的内容上分为:本地文件、字节数组
  3. //参数说明:
  4. /// <param name="url">接口路径</param>
  5. /// <param name="displayName">文件显示名称</param>
  6. /// <param name="filePath">待上传的本地文件路径</param>
  7. /// <param name="fileData">待上传的字节数组</param>
  8. /// <param name="data">请求数据</param>
  9. //上传文件返回响应字符串
  10. public string UploadFile(string url, string displayName, string filePath, object data = null)
  11. //上传文件返回泛型消息对象
  12. public BoolMessage<T> UploadFile<T>(string url, string displayName, string filePath, object data = null)
  13. //上传字节数组
  14. public string UploadByte(string url, string displayName, byte[] fileData, object data = null)
  15. //上传字节数组
  16. public BoolMessage<T> UploadByte<T>(string url, string displayName, byte[] fileData, object data = null)

文件下载

  1. //从返回值分为:返回通用消息对象、返回泛型消息对象
  2. //从下载的方法上分为:GET、POST,默认使用GET方法
  3. //参数说明:
  4. /// <param name="url">接口路径</param>
  5. /// <param name="data">请求数据</param>
  6. /// <param name="savePath">文件本地保存路径</param>
  7. //用Get方法下载文件到本地
  8. public BoolMessage Download(string url, object data, string savePath)
  9. //用Get方法下载文件到字节数组
  10. public BoolMessage<byte[]> Download(string url, object data = null)
  11. //用Post方法下载文件到本地
  12. public BoolMessage DownloadPost(string url, object data, string savePath)
  13. //用Post方法下载文件到字节数组
  14. public BoolMessage<byte[]> DownloadPost(string url, object data = null)

事件

子类可以重写这两个方法

  1. /// <summary>
  2. /// 在请求发送前触发
  3. /// </summary>
  4. /// <param name="request">请求对象</param>
  5. /// <returns>如果返回false,则终止请求</returns>
  6. protected virtual bool OnBeforeRequest(HttpRequestMessage request)
  7. {
  8. return true;
  9. }
  10. /// <summary>
  11. /// 在请求成功后触发
  12. /// </summary>
  13. /// <param name="response">响应对象</param>
  14. protected virtual void OnAfterRequest(HttpResponseMessage response)
  15. {
  16. }

权限子系统通信类

权限通讯类继承自WebApi类,在构造函数中传入appId参数,同时重写了OnBeforeRequest方法,实现了在请求发送之前添加Header参数,符合了服务端接口请求规范。

  1. using System;
  2. using System.Globalization;
  3. using System.Net.Http;
  4. using XCI.Core;
  5. using XCI.Helper;
  6. namespace XCI.Sys
  7. {
  8. /// <summary>
  9. /// 系统Api接口
  10. /// </summary>
  11. public class SysWebApi : WebApi
  12. {
  13. private string _appId;
  14. /// <summary>
  15. /// 初始化系统Api接口
  16. /// </summary>
  17. /// <param name="appId">应用Id</param>
  18. /// <param name="baseUrl">服务器基地址</param>
  19. /// <param name="timeout">超时间隔</param>
  20. /// <param name="useProxy">是否使用代理</param>
  21. public SysWebApi(string appId, string baseUrl, TimeSpan timeout, bool useProxy) : base(baseUrl, timeout, useProxy)
  22. {
  23. _appId = appId;
  24. }
  25. /// <summary>
  26. /// 在请求前触发
  27. /// </summary>
  28. /// <param name="request">请求对象</param>
  29. /// <returns>如果返回false,则终止请求</returns>
  30. protected override bool OnBeforeRequest(HttpRequestMessage request)
  31. {
  32. request.Headers.Add("appId", _appId);//app
  33. request.Headers.Add("timestamp", DateTimeHelper.GetTimeStamp().ToString(CultureInfo.InvariantCulture));//时间戳
  34. request.Headers.Add("token", SysRuntime.CurrentUser?.Token);//token
  35. return true;
  36. }
  37. }
  38. }

文件上传下载服务

上面介绍的通讯类类似于工具类,而文件上传和下载需要编写服务端,框架已经默认实现了的上传和下载功能,客户端使用FileUploadService类来完成调用。

  1. namespace XCI.Sys.Service
  2. {
  3. public class FileUploadService
  4. {
  5. /// <summary>
  6. /// 上传文件
  7. /// </summary>
  8. /// <param name="folder">服务端文件夹(可为空,默认为当前日期)</param>
  9. /// <param name="fileName">文件保存名称(可为空,默认为自动生成)</param>
  10. /// <param name="displayName">文件显示名称</param>
  11. /// <param name="localPath">待上传的本地文件路径</param>
  12. public FileModel UploadFile(string folder, string fileName,
  13. string displayName, string localPath);
  14. /// <summary>
  15. /// 上传文件
  16. /// </summary>
  17. /// <param name="folder">服务端文件夹(可为空,默认为当前日期)</param>
  18. /// <param name="fileName">文件保存名称(可为空,默认为自动生成)</param>
  19. /// <param name="displayName">文件显示名称</param>
  20. /// <param name="fileData">待上传的二进制</param>
  21. public FileModel UploadByte(string folder, string fileName,
  22. string displayName, byte[] fileData);
  23. /// <summary>
  24. /// 下载文件
  25. /// </summary>
  26. /// <param name="serverPath">服务端文件路径</param>
  27. /// <param name="md5">文件md5</param>
  28. public byte[] Download(string serverPath, string md5);
  29. /// <summary>
  30. /// 下载文件
  31. /// </summary>
  32. /// <param name="serverPath">服务端文件路径</param>
  33. /// <param name="localPath">本地存储文件路径</param>
  34. /// <param name="md5">文件md5</param>
  35. public void Download(string serverPath, string localPath,string md5);
  36. /// <summary>
  37. /// 删除文件
  38. /// </summary>
  39. /// <param name="serverPath">服务端文件路径</param>
  40. /// <returns>成功返回true</returns>
  41. public bool Delete(string serverPath);
  42. }
  43. }

示例

  1. 用GET方法请求公司网站
  1. WebApi api = new WebApi();
  2. var result = api.Get("http://www.xci96716.com/");
  3. MessageBoxHelper.ShowMessage(result);
  1. 用POST方法请求服务器时间
  1. SysWebApi api = new SysWebApi("1117664844619845632", "http://localhost:8765", TimeSpan.FromSeconds(10), false);
  2. //请求服务,显示服务响应字符串
  3. var result = api.Post("/api/sys/system/datetime");
  4. MessageBoxHelper.ShowMessage(result);
  5. //请求服务,将服务响应字符串转为泛型消息对象,并显示泛型对象值
  6. var resultMessage = api.Post<string>("/api/sys/system/datetime");
  7. MessageBoxHelper.ShowMessage(resultMessage.Data);
  1. 上传文件
  1. //自动生成文件夹和文件名
  2. var fileInfo1 = FileUploadService.Instance.UploadFile(null, null, "风景.jpg", "R:\\5.jpg");
  3. MessageBoxHelper.ShowMessage(JsonHelper.Serialize(fileInfo1, Formatting.Indented));
  4. //设置目录名称,并且按年 - 月自动创建文件夹,设置文件保存名称
  5. var fileInfo2 = FileUploadService.Instance.UploadFile($"/customer/{DateTime.Now:yyyy-MM}", "abc.jpg", "风景.jpg", "R:\\5.jpg");
  6. MessageBoxHelper.ShowMessage(JsonHelper.Serialize(fileInfo2, Formatting.Indented));
  7. //使用二进制数组上传
  8. using (var stream = File.OpenRead("R:\\35.jpg"))
  9. {
  10. byte[] bytes = new byte[stream.Length];
  11. stream.Read(bytes, 0, bytes.Length);
  12. var fileInfo3 = FileUploadService.Instance.UploadByte(null, null, "风光.jpg", bytes);
  13. MessageBoxHelper.ShowMessage(JsonHelper.Serialize(fileInfo3, Formatting.Indented));
  14. }
  1. 下载文件
  1. //下载文件到本地文件
  2. var serverUrl = "/res/upload/1117664844619845632/20190711/5390705aa4d74b7cb7c9efdefa83280d.jpg";
  3. var localUrl = $"R:/风景{ Path.GetExtension(serverUrl)}";
  4. FileUploadService.Instance.Download(serverUrl, localUrl, null);
  5. MessageBoxHelper.ShowMessage($"文件下载成功,保存到 {localUrl}");
  6. //下载文件到二进制数组
  7. var serverUrl = "/res/upload/1117664844619845632/20190711/abc.jpg";
  8. byte[] fileBytes = FileUploadService.Instance.Download(serverUrl, null);
  9. Image img = ImageHelper.FromArray(fileBytes);
  10. pictureEdit1.Image = img;
  11. //下载文件时传递md5
  12. var serverUrl = "/res/upload/1117664844619845632/20190711/5390705aa4d74b7cb7c9efdefa83280d.jpg";
  13. var localUrl = $"R:/风景{ Path.GetExtension(serverUrl)}";
  14. var md5 = string.Empty;
  15. if (File.Exists(localUrl))
  16. {
  17. md5 = IOHelper.GetFileMd5(localUrl);
  18. }
  19. FileUploadService.Instance.Download(serverUrl, localUrl, md5);
  20. MessageBoxHelper.ShowMessage($"文件下载成功,保存到 {localUrl}");
  1. 删除服务端文件
  1. //删除服务器文件
  2. var result = FileUploadService.Instance.Delete("/res/upload/1117664844619845632/20190711/82609296ce6c4cd1ac8e958c96da1a90.jpg");
  3. if (result)
  4. {
  5. MessageBoxHelper.ShowMessage("删除成功");
  6. }

服务基类

客户端所有的业务处理都是通过调用服务端的接口来完成的,按照要求每个业务要有一个独立的Service来完成对服务端接口的封装。为了调用服务端接口更方便,每个业务服务需要继承泛型服务基类BaseService

使用服务基类有以下几个关键点:

1. 单例对象

服务类并没有状态字段,所以只需要使用单例模式即可,每次都新创建服务示例没有任何意义。

使用方法:

  1. public class ParamService : BaseService<SysParam>
  2. {
  3. public static readonly ParamService Instance = new ParamService();
  4. }

2. 设置接口根地址

由于每个接口服务的前缀几乎是一样的,可以设置接口根地址,并通过GetUrl方法,快捷的生成一个接口地址。

使用方法:

  1. public class ParamService : BaseService<SysParam>
  2. {
  3. //设置服务根地址
  4. protected override string RootUrl => "/api/sys/param/";
  5. }
  6. //构建地址
  7. var url = GetUrl("insert");//获取新增地址 /api/sys/param/insert
  8. var url = GetUrl("update");//获取修改地址 /api/sys/param/update
  9. var url = GetUrl("delete");//获取删除地址 /api/sys/param/delete
  10. var url = GetUrl("selectById",1);//获取指定主键的地址 /api/sys/param/selectById/1
  11. var url = GetUrl("selectByCode","user",2);//获取指定主键的地址 /api/sys/param/selectByCode/user/2
  12. var url = GetUrl("selectList");//获取列表地址 /api/sys/param/selectList
  13. var url = GetUrl("selectPageList");//获取分页列表地址 /api/sys/param/selectPageList

3. 获取主键

框架中使用了整数作为主键,每个整数使用了雪花ID算法由服务端生成,所以在使用前要调用服务端方法来生成。

调用方法:

  1. /// <summary>
  2. /// 新建参数模型
  3. /// </summary>
  4. public SysParam New()
  5. {
  6. return new SysParam
  7. {
  8. //调用服务基类中的NewId方法
  9. Id = NewId()
  10. };
  11. }

4. 分页参数转换

分页参数封装在类PageParam中,有以下字段:

  • PageIndex //页码索引,从1开始
  • PageSize //每页记录数
  • SortName //排序字段名称
  • SortDir //排序方式(asc/desc)

调用服务基类中的方法ToPageMap把分页参数对象转为Map对象,转换过程中进行数据验证,保障发送给服务端参数的正确性。

5. Map集合对象

Map对象继承自Dictionary,表示一个键值对集合,扩展了一些链式方法,方便操作。

  1. using System.Collections.Generic;
  2. using XCI.Helper;
  3. namespace XCI.Core
  4. {
  5. /// <summary>
  6. /// 字符字典
  7. /// </summary>
  8. public class Map : Dictionary<string, object>
  9. {
  10. public static Map New => new Map();
  11. /// <summary>
  12. /// 添加键值对
  13. /// </summary>
  14. /// <param name="key">键</param>
  15. /// <param name="value">值</param>
  16. public new Map Add(string key, object value)
  17. {
  18. this[key] = value;
  19. return this;
  20. }
  21. /// <summary>
  22. /// 添加对象(属性名为键,属性值为值)
  23. /// </summary>
  24. /// <param name="obj">对象</param>
  25. public Map AddObject(object obj)
  26. {
  27. var data = ObjectHelper.GetPropertyKeyValuePair(obj);
  28. foreach (KeyValuePair<string, object> item in data)
  29. {
  30. this[item.Key] = item.Value;
  31. }
  32. return this;
  33. }
  34. /// <summary>
  35. /// 如果值不为空字符串,则添加键值对
  36. /// </summary>
  37. /// <param name="key">键</param>
  38. /// <param name="value">值</param>
  39. public Map IsNotEmpty(string key, object value)
  40. {
  41. if (value != null && !string.IsNullOrEmpty(value.ToString()))
  42. {
  43. this[key] = value.ToString();
  44. }
  45. return this;
  46. }
  47. /// <summary>
  48. /// 如果值不为空对象,则添加键值对
  49. /// </summary>
  50. /// <param name="key">键</param>
  51. /// <param name="value">值</param>
  52. public Map IfNotNull(string key, object value)
  53. {
  54. if (value != null)
  55. {
  56. this[key] = value.ToString();
  57. }
  58. return this;
  59. }
  60. /// <summary>
  61. /// 如果条件为真,则添加键值对
  62. /// </summary>
  63. /// <param name="key">键</param>
  64. /// <param name="value">值</param>
  65. public Map If(bool condition, string key, object value)
  66. {
  67. if (condition)
  68. {
  69. this[key] = value;
  70. }
  71. return this;
  72. }
  73. /// <summary>
  74. /// 合并两个Map集合
  75. /// </summary>
  76. /// <param name="map">待合并的Map集合</param>
  77. public Map Merge(Map map)
  78. {
  79. foreach (KeyValuePair<string,object> item in map)
  80. {
  81. this[item.Key] = item.Value;
  82. }
  83. return this;
  84. }
  85. }
  86. }

使用方法:

  1. //添加键值对
  2. Map.New.Add("key", key).Add("deptId", deptId).Add("status", status);
  3. //添加对象
  4. HistoryFilter filter = new HistoryFilter();
  5. Map.New.AddObject(filter)

6. 公共方法

基类包装了常用的接口方法

  1. ExistByIdCore // 检查主键是否存在
  2. ExistByCodeCore // 检查编码是否存在
  3. ExistByNameCore // 检查名称是否存在
  4. InsertCore //新建数据
  5. UpdateCore //修改数据
  6. DeleteByIdCore //根据主键删除数据
  7. DeleteByIdsCore //根据主键字符串删除数据
  8. UpdateStatusByIdCore //根据主键修改状态
  9. UpdateStatusByIdsCore //根据主键字符串删除数据
  10. BatchUpdateValuesCore //批量修改字段值
  11. SelectByIdCore //根据主键获取数据
  12. SelectByCodeCore //根据编码获取数据
  13. SelectPageListCore //查询分页列表数据
  14. SelectListCore //查询列表数据
  15. ExportCore //导出数据
  16. bool RefreshCacheCore //刷新服务端缓存

服务基类源码

  1. using System.Collections.Generic;
  2. using XCI.Core;
  3. using XCI.Windows.Extensions;
  4. namespace XCI.Sys.Service
  5. {
  6. /// <summary>
  7. /// 服务基类
  8. /// </summary>
  9. public class BaseService<T> where T : class
  10. {
  11. /// <summary>
  12. /// 根地址
  13. /// </summary>
  14. protected virtual string RootUrl { get; }
  15. /// <summary>
  16. /// 获取接口地址
  17. /// </summary>
  18. /// <param name="name">接口名称</param>
  19. /// <param name="paths">路径参数</param>
  20. protected string GetUrl(string name, params string[] paths)
  21. {
  22. var url = string.Concat(RootUrl, name);
  23. if (paths != null && paths.Length > 0)
  24. {
  25. foreach (var path in paths)
  26. {
  27. url = string.Concat(url, "/", path);
  28. }
  29. }
  30. return url;
  31. }
  32. /// <summary>
  33. /// 转为分页Map
  34. /// </summary>
  35. /// <param name="pageParam">分页参数</param>
  36. protected Map ToPageMap(PageParam pageParam)
  37. {
  38. Map map = new Map();
  39. if (pageParam.PageIndex.HasValue)
  40. {
  41. map.Add("pageIndex", pageParam.PageIndex.Value.ToString());
  42. }
  43. if (pageParam.PageSize.HasValue)
  44. {
  45. map.Add("pageSize", pageParam.PageSize.Value.ToString());
  46. }
  47. if (!string.IsNullOrEmpty(pageParam.SortName) && !string.IsNullOrEmpty(pageParam.SortDir))
  48. {
  49. map.Add("sortName", pageParam.SortName);
  50. map.Add("sortDir", pageParam.SortDir);
  51. }
  52. return map;
  53. }
  54. /// <summary>
  55. /// 创建新Id
  56. /// </summary>
  57. protected string NewId()
  58. {
  59. return SysService.Instance.GetId();
  60. }
  61. /// <summary>
  62. /// 检查主键是否存在
  63. /// </summary>
  64. /// <param name="id">主键</param>
  65. protected bool ExistByIdCore(string id)
  66. {
  67. var url = GetUrl(SysConst.ApiExistByIdName, id);
  68. return SysRuntime.Api.Post<bool>(url).EnsureSuccess().Data;
  69. }
  70. /// <summary>
  71. /// 检查编码是否存在
  72. /// </summary>
  73. /// <param name="code">编码</param>
  74. protected bool ExistByCodeCore(string code)
  75. {
  76. var url = GetUrl(SysConst.ApiExistByCodeName, code);
  77. return SysRuntime.Api.Post<bool>(url).EnsureSuccess().Data;
  78. }
  79. /// <summary>
  80. /// 检查名称是否存在
  81. /// </summary>
  82. /// <param name="name">名称</param>
  83. protected bool ExistByNameCore(string name)
  84. {
  85. var url = GetUrl(SysConst.ApiExistByNameName, name);
  86. return SysRuntime.Api.Post<bool>(url).EnsureSuccess().Data;
  87. }
  88. /// <summary>
  89. /// 新建数据
  90. /// </summary>
  91. /// <param name="model">数据模型</param>
  92. protected bool InsertCore(T model)
  93. {
  94. var url = GetUrl(SysConst.ApiInsertName);
  95. return SysRuntime.Api.PostJsonAsMessage(url, model).EnsureSuccess().Success;
  96. }
  97. /// <summary>
  98. /// 修改数据
  99. /// </summary>
  100. /// <param name="model">数据模型</param>
  101. protected bool UpdateCore(T model)
  102. {
  103. var url = GetUrl(SysConst.ApiUpdateName);
  104. return SysRuntime.Api.PostJsonAsMessage(url, model).EnsureSuccess().Success;
  105. }
  106. /// <summary>
  107. /// 删除数据
  108. /// </summary>
  109. /// <param name="id">主键</param>
  110. protected bool DeleteByIdCore(string id)
  111. {
  112. var url = GetUrl(SysConst.ApiDeleteName);
  113. var map = new Map
  114. {
  115. { SysConst.FIdName, id }
  116. };
  117. return SysRuntime.Api.PostAsMessage(url, map).EnsureSuccess().Success;
  118. }
  119. /// <summary>
  120. /// 删除数据
  121. /// </summary>
  122. /// <param name="ids">主键字符串</param>
  123. protected bool DeleteByIdsCore(string ids)
  124. {
  125. var url = GetUrl(SysConst.ApiDeleteName);
  126. var map = new Map
  127. {
  128. { SysConst.FIdsName, ids }
  129. };
  130. return SysRuntime.Api.PostAsMessage(url, map).EnsureSuccess().Success;
  131. }
  132. /// <summary>
  133. /// 修改状态
  134. /// </summary>
  135. /// <param name="id">主键</param>
  136. /// <param name="status">状态 true:启用 false:禁用</param>
  137. /// <returns>成功返回true</returns>
  138. protected bool UpdateStatusByIdCore(string id, bool status)
  139. {
  140. var url = GetUrl(SysConst.ApiUpdateStatusName);
  141. var map = new Map
  142. {
  143. { SysConst.FIdName, id },
  144. { SysConst.FStatusName, status.ToString() }
  145. };
  146. return SysRuntime.Api.PostAsMessage(url, map).EnsureSuccess().Success;
  147. }
  148. /// <summary>
  149. /// 修改状态
  150. /// </summary>
  151. /// <param name="ids">主键字符串</param>
  152. /// <param name="status">状态 true:启用 false:禁用</param>
  153. /// <returns>成功返回true</returns>
  154. protected bool UpdateStatusByIdsCore(string ids, bool status)
  155. {
  156. var url = GetUrl(SysConst.ApiUpdateStatusName);
  157. var map = new Map
  158. {
  159. { SysConst.FIdsName, ids },
  160. { SysConst.FStatusName, status.ToString() }
  161. };
  162. return SysRuntime.Api.PostAsMessage(url, map).EnsureSuccess().Success;
  163. }
  164. /// <summary>
  165. /// 批量修改字段值
  166. /// </summary>
  167. /// <param name="keyValues">修改的数据集合</param>
  168. /// <returns>成功返回true</returns>
  169. protected bool BatchUpdateValuesCore(List<PrimaryKeyValue> keyValues)
  170. {
  171. var url = GetUrl(SysConst.ApiBatchUpdateValuesName);
  172. return SysRuntime.Api.PostJsonAsMessage(url, keyValues).EnsureSuccess().Success;
  173. }
  174. /// <summary>
  175. /// 根据主键获取数据
  176. /// </summary>
  177. /// <param name="id">主键</param>
  178. /// <returns>成功返回模型对象</returns>
  179. protected T SelectByIdCore(string id)
  180. {
  181. var url = GetUrl(SysConst.ApiSelectByIdName, id);
  182. return SysRuntime.Api.Post<T>(url).EnsureSuccess().Data;
  183. }
  184. /// <summary>
  185. /// 根据编码获取数据
  186. /// </summary>
  187. /// <param name="code">编码</param>
  188. /// <returns>成功返回模型对象</returns>
  189. protected T SelectByCodeCore(string code)
  190. {
  191. var url = GetUrl(SysConst.ApiSelectByCodeName, code);
  192. return SysRuntime.Api.Post<T>(url).EnsureSuccess().Data;
  193. }
  194. /// <summary>
  195. /// 刷新服务端缓存
  196. /// </summary>
  197. protected bool RefreshCacheCore()
  198. {
  199. var url = GetUrl(SysConst.ApiRefreshCacheName);
  200. return SysRuntime.Api.PostAsMessage(url).EnsureSuccess().Success;
  201. }
  202. /// <summary>
  203. /// 查询分页数据
  204. /// </summary>
  205. protected PageList<T> SelectPageListCore(Map map = null)
  206. {
  207. var url = GetUrl(SysConst.ApiSelectPageListName);
  208. return SysRuntime.Api.Post<PageList<T>>(url, map).EnsureSuccess().Data;
  209. }
  210. /// <summary>
  211. /// 查询数据
  212. /// </summary>
  213. protected List<T> SelectListCore(Map map = null)
  214. {
  215. var url = GetUrl(SysConst.ApiSelectListName);
  216. return SysRuntime.Api.Post<List<T>>(url, map).EnsureSuccess().Data;
  217. }
  218. /// <summary>
  219. /// 导出数据
  220. /// </summary>
  221. protected byte[] ExportCore(Map map = null)
  222. {
  223. var url = GetUrl(SysConst.ApiExportName);
  224. return SysRuntime.Api.DownloadPost(url, map).EnsureSuccess().Data;
  225. }
  226. }
  227. }

系统参数服务示例

  1. using System;
  2. using System.Collections.Generic;
  3. using XCI.Sys.Model;
  4. using XCI.Core;
  5. using XCI.Windows.Extensions;
  6. namespace XCI.Sys.Service
  7. {
  8. /// <summary>
  9. /// 系统参数服务
  10. /// </summary>
  11. public class ParamService : BaseService<SysParam>
  12. {
  13. public static readonly ParamService Instance = new ParamService();
  14. protected override string RootUrl => "/api/sys/param/";
  15. /// <summary>
  16. /// 新建参数模型
  17. /// </summary>
  18. public SysParam New()
  19. {
  20. return new SysParam
  21. {
  22. Id = NewId()
  23. };
  24. }
  25. /// <summary>
  26. /// 复制参数模型
  27. /// </summary>
  28. /// <param name="original">原模型</param>
  29. public SysParam Copy(SysParam original)
  30. {
  31. if (original == null) throw new ArgumentNullException(nameof(original));
  32. var model = original?.Clone();
  33. model.Id = NewId();
  34. return model;
  35. }
  36. /// <summary>
  37. /// 检查参数编码是否存在
  38. /// </summary>
  39. /// <param name="code">参数编码</param>
  40. public bool ExistByCode(string code)
  41. {
  42. return ExistByCodeCore(code);
  43. }
  44. /// <summary>
  45. /// 新建参数
  46. /// </summary>
  47. /// <param name="model">参数模型对象</param>
  48. /// <returns>成功返回true</returns>
  49. public bool Insert(SysParam model)
  50. {
  51. return InsertCore(model);
  52. }
  53. /// <summary>
  54. /// 修改参数
  55. /// </summary>
  56. /// <param name="model">参数模型对象</param>
  57. /// <returns>成功返回true</returns>
  58. public bool Update(SysParam model)
  59. {
  60. return UpdateCore(model);
  61. }
  62. /// <summary>
  63. /// 删除参数
  64. /// </summary>
  65. /// <param name="ids">主键字符串</param>
  66. /// <returns>成功返回true</returns>
  67. public bool Delete(string ids)
  68. {
  69. return DeleteByIdsCore(ids);
  70. }
  71. /// <summary>
  72. /// 根据主键获取参数对象
  73. /// </summary>
  74. /// <param name="id">参数主键</param>
  75. public SysParam SelectById(string id)
  76. {
  77. return SelectByIdCore(id);
  78. }
  79. /// <summary>
  80. /// 根据参数编码获取参数对象
  81. /// </summary>
  82. /// <param name="code">参数编码</param>
  83. /// <returns>成功返回模型对象</returns>
  84. public SysParam SelectByCode(string code)
  85. {
  86. return SelectByCodeCore(code);
  87. }
  88. /// <summary>
  89. /// 根据编码查询单个参数值
  90. /// </summary>
  91. /// <param name="code">参数编码</param>
  92. /// <param name="defaultValue">如果没有找到指定编码的参数,则返回此默认值</param>
  93. /// <returns>返回指定编码的参数值</returns>
  94. public string SelectValueByCode(string code, string defaultValue)
  95. {
  96. var url = GetUrl("selectValueByCode");
  97. var map = Map.New.Add("code", code).Add("defaultValue", defaultValue);
  98. return SysRuntime.Api.Post<string>(url, map).EnsureSuccess().Data;
  99. }
  100. /// <summary>
  101. /// 查询参数分页列表
  102. /// </summary>
  103. /// <param name="paged">分页参数</param>
  104. /// <param name="key">编码/名称关键字</param>
  105. public PageList<SysParam> SelectPageList(PageParam paged, string key)
  106. {
  107. var map = ToPageMap(paged).Add(SysConst.FKeyName, key);
  108. return SelectPageListCore(map);
  109. }
  110. /// <summary>
  111. /// 查询参数列表
  112. /// </summary>
  113. /// <param name="key">编码/名称关键字</param>
  114. public List<SysParam> SelectList(string key)
  115. {
  116. var map = Map.New.Add(SysConst.FKeyName, key);
  117. return SelectListCore(map);
  118. }
  119. /// <summary>
  120. /// 导出参数列表
  121. /// </summary>
  122. /// <param name="key">编码/名称关键字</param>
  123. public byte[] Export(string key)
  124. {
  125. var map = Map.New.Add(SysConst.FKeyName, key);
  126. return ExportCore(map);
  127. }
  128. /// <summary>
  129. /// 刷新服务端参数缓存
  130. /// </summary>
  131. public bool RefreshCache()
  132. {
  133. return RefreshCacheCore();
  134. }
  135. }
  136. }