利用委托与Lambada创建和调用webapi接口
前言
现在项目中用的是webapi,其中有以下问题:
1.接口随着开发的增多逐渐增加相当庞大。
2.接口调用时不好管理。
以上是主要问题,对此就衍生了一个想法:
如果每一个接口都一个配置文件来管理,每个配置文件能清晰表示处理接口文件,地址,参数,返回值,那么通过这个配置文件,就能很好的管理起来我们所有的webapi接口不是吗?
有了这个思路之后就有了以下的实现:
1.具体实现:
public void Build_Apis()
{
))
{
var vatt = ass.GetCustomAttribute<AssemblyFileVersionAttribute>();
var tatt = ass.GetCustomAttribute<AssemblyTitleAttribute>();
var datt = ass.GetCustomAttribute<QuickWebApiDllAttribute>();
apis.Clear();
var input_types = new List<Type>();
foreach (var type in ass.GetTypes())
{
var attr = type.GetCustomAttribute<QuickWebApiAttribute>();
if (attr != null)
{
WebApiNode api = new WebApiNode(datt.Domain) { Name = attr.name, Service = attr.service, Route = attr.route, Comment = attr.comment, Version = vatt.Version, Title = tatt.Title };
foreach (var mi in type.GetMethods())
{
var att = mi.GetCustomAttribute<QuickWebApiAttribute>();
if (att != null)
{
var act = new WebApiMethod() { Action = mi.Name, Code = att.service, Method = att.methodtype, Name = string.IsNullOrWhiteSpace(att.name) ? mi.Name : att.name, Comment = att.comment, OutputType = att.resultype };
foreach (var arg in mi.GetParameters())
{
var mdatt = arg.ParameterType.GetCustomAttribute<DescriptionAttribute>();
act.Params.Add(new WebApiMethodParam() { Name = arg.Name, TypeName = arg.ParameterType.Name, DefaultValue = string.IsNullOrWhiteSpace(arg.DefaultValue.ToString()) ? "无默认值" : arg.DefaultValue.ToString(), Desc = mdatt == null ? "" : mdatt.Description });
if (arg.ParameterType.IsClass && arg.ParameterType != typeof(string))
{
if (!input_types.Exists(t => t.Name == arg.ParameterType.Name))
input_types.Add(arg.ParameterType);
}
}
if (!api.Methods.Exists(a => a.Action == act.Action))
api.Methods.Add(act);
if (att.resultype != null && att.resultype.IsClass && att.resultype != typeof(string))
{
if (!input_types.Exists(t => t.Name == att.resultype.Name))
input_types.Add(att.resultype);
}
}
}
if (!apis.Exists(a => a.Service == api.Service))
apis.Add(api);
}
}
Build_Apids_Config(apis, datt.Name);
Build_Apids_Doc(apis, datt.Name, input_types);
}
}
1.1:其中Build_Apis()方法,是系统根据,webapi接口描述,创建的对应的接口服务配置文件操作。
配置如下:
生成接口文件如下:
接口的实现
接下来只需你把xml文件引用到你要调用的站点下即可。
public string Load_Apis()
{
var files = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "apis_*.xml", System.IO.SearchOption.AllDirectories);
apis.Clear();
foreach (var path in files)
{
var jss = System.IO.File.ReadAllText(path);
var _apis = Deserialize<List<WebApiNode>>(jss);
) continue;
foreach (var api in _apis)
{
if (apis.Exists(a => a.Service == api.Service)) continue;
apis.Add(api);
}
}
return string.Format("service:{0}, action:{1}", apis.Count, apis.Sum(a => a.Methods.Count));
}
1.2:其中Load_Apis()方式是在程序启动时加载webapi服务配置文件的操作,在这不再累述。
public class webapi<T, tresp> where tresp : class,new()
{
public webapi() { }
public webapi(string service_prefix)
{
_service_prefix = service_prefix;
}
public webapi(long service_prefix_id)
{
_service_prefix = service_prefix_id.ToString();
}
protected string build_server(string srv)
{
return string.IsNullOrWhiteSpace(_service_prefix) ? srv : string.Format("{0}_{1}", _service_prefix, srv);
}
string _service_prefix;
public result<tresp> invoke(Expression<Func<T, apiaction_l>> func, long args1)
{
return _invoke(func.Body, args1);
}
public result<tresp> invoke(Expression<Func<T, apiaction_ll>> func, long args1, long args2)
{
return _invoke(func.Body, args1, args2);
}
public result<tresp> invoke(Expression<Func<T, apiaction_li>> func, long args1, int args2)
{
return _invoke(func.Body, args1, args2);
}
public result<tresp> invoke(Expression<Func<T, apiaction_ls>> func, long args1, string args2)
{
return _invoke(func.Body, args1, args2);
}
//public result<tresp> invoke<treq>(Expression<Func<T, apiaction_s<treq>>> func, treq args1) where treq : struct
//{
// return _invoke(func.Body, args1);
//}
public result<tresp> invoke(Expression<Func<T, apiaction_i>> func, int args1)
{
return _invoke(func.Body, args1);
}
public result<tresp> invoke(Expression<Func<T, apiaction_ii>> func, int args1, int args2)
{
return _invoke(func.Body, args1, args2);
}
public result<tresp> invoke(Expression<Func<T, apiaction_il>> func, int args1, long args2)
{
return _invoke(func.Body, args1, args2);
}
public result<tresp> invoke(Expression<Func<T, apiaction_is>> func, int args1, string args2)
{
return _invoke(func.Body, args1, args2);
}
public result<tresp> invoke(Expression<Func<T, apiaction_ss>> func, string args1, string args2)
{
return _invoke(func.Body, args1, args2);
}
public result<tresp> invoke(Expression<Func<T, apiaction_sss>> func, string args1, string args2, string args3)
{
return _invoke(func.Body, args1, args2, args3);
}
public result<tresp> invoke<treq>(Expression<Func<T, apiaction_o<treq>>> func, treq data) where treq : class,new()
{
if (data != null && data is String)
{
return _invoke(func.Body, data);
}
return _invoke_data<treq>(func.Body, data);
}
public result<tresp> invoke(Expression<Func<T, apiaction>> func)
{
return _invoke_data<object>(func.Body, null);
}
result<tresp> _invoke_data<treq>(Expression exp, treq data) where treq : class
{
var method = ((exp as UnaryExpression).Operand as MethodCallExpression);
string code = ((method.Object as ConstantExpression).Value as MethodInfo).Name;
foreach (var m in method.Arguments)
{
if (m.Type == typeof(T))
{
var attr = m.Type.GetCustomAttribute<QuickWebApiAttribute>();
if (attr != null)
{
return new invoker(build_server(attr.service)).Excute<tresp>(code, data);
}
}
}
, "未能找到合适的api定义");
}
result<tresp> _invoke(Expression exp, params object[] args)
{
var method = ((exp as UnaryExpression).Operand as MethodCallExpression);
string code = ((method.Object as ConstantExpression).Value as MethodInfo).Name;
foreach (var m in method.Arguments)
{
if (m.Type == typeof(T))
{
var attr = m.Type.GetCustomAttribute<QuickWebApiAttribute>();
StringBuilder sb = new StringBuilder();
var pis = m.Type.GetMethod(code).GetParameters();
; i < pis.Length; i++)
{
sb.AppendFormat("{0}={1}&", pis[i].Name, args[i] is DateTime ? ((DateTime)args[i]).ToString("yyyy-MM-dd HH:mm:ss") : args[i]);
}
if (attr != null)
{
return new invoker(build_server(attr.service)).Excute<tresp>(code, sb.ToString());
}
}
}
, "未能找到合适的api定义");
}
}
1.3:其中 result<tresp> _invoke是:通过lambda对传递过来的委托,进行相应的反射操作。
其中委托定义如下:
public delegate IHttpActionResult apiaction();
public delegate IHttpActionResult apiaction_l(long args);
public delegate IHttpActionResult apiaction_ll(long args1, long args2);
public delegate IHttpActionResult apiaction_li(long args1, int arg2);
public delegate IHttpActionResult apiaction_ls(long args1, string args2);
public delegate IHttpActionResult apiaction_i(int args1);
public delegate IHttpActionResult apiaction_ii(int args1, int args2);
public delegate IHttpActionResult apiaction_is(int args1, string args2);
public delegate IHttpActionResult apiaction_il(int args1, long args2);
public delegate IHttpActionResult apiaction_si(string args1, int args2);
public delegate IHttpActionResult apiaction_ss(string args1, string args2);
public delegate IHttpActionResult apiaction_sl(string args1, long args2);
public delegate IHttpActionResult apiaction_sss(string args1, string args2, string args3);
public delegate IHttpActionResult apiaction_o<treq>(treq data) where treq : class,new();
注:目前delegate只支持三个参数以内的接口(且参数类型目前仅支持int,long,string),如果参数不符合条件可传递对象。
以上为具体实现至于有不了解的可以在文章顶部下载代码也可以,点击公共中qq与我联系。
2.下面我来写一下它的使用:
2.1.初始化:
在global中添加如下代码:
2.2.在mvc中调用:
利用委托与Lambada创建和调用webapi接口的更多相关文章
- WebApi接口 - 如何在应用中调用webapi接口
很高兴能再次和大家分享webapi接口的相关文章,本篇将要讲解的是如何在应用中调用webapi接口:对于大部分做内部管理系统及类似系统的朋友来说很少会去调用别人的接口,因此可能在这方面存在一些困惑,希 ...
- 如何使用程序调用webApi接口
如何使用程序调用webApi接口 在C#中,传统调用HTTP接口一般有两种办法: WebRequest/WebResponse组合的方法调用 WebClient类进行调用. 第一种方法抽象程度较低,使 ...
- php中创建和调用webservice接口示例
php中创建和调用webservice接口示例 这篇文章主要介绍了php中创建和调用webservice接口示例,包括webservice基本知识.webservice服务端例子.webservi ...
- aspx页面调用webapi接口报错:远程服务器返回错误:(500)内部服务器错误
代码在运行到response = (HttpWebResponse)request.GetResponse();就开始报错 原因:可能因为所调用的接口不存在或者接口中存在错误,可用postman测试接 ...
- 【C#】 创建和调用webapi
二,,通过普通的路由调用,,路径写到http://localhost:29920/api/Players 即 Api/controller 为止
- 使用httpclient异步调用WebAPI接口
最近的工作需要使用Bot Framework调用原有的WebAPI查询数据,查找了一些方法,大部分都是使用HttpClient调用的,现时贴出代码供参考 using System; using Sys ...
- 使用HttpClient调用WebAPI接口,含WebAPI端示例
API端: using log4net; using System; using System.Collections.Generic; using System.IO; using System.L ...
- 调用WebAPI接口地址返回序列化的JSON对象中的属性都加了个k__BackingField关键字的解决办法
1.问题现象: 2.造成此问题的原因是返回的结果对象实体上面加了个可序列号特效 [Serializable].去掉就可以了. 3.解决后的效果:
- WebApi(6) 后台C#调用WebApi
https://www.cnblogs.com/cxd1008/p/6640015.html 今天来写一下后台C#代码如何访问webapi 这里使用HttpClient方法访问webapi也是很常用的 ...
随机推荐
- Win10激活KMS
Windows 10是目前微软主推的Windows系统,Win10 相对之前的Win7/8是吸取二者之长,发展而来! 目前新装的Windows10默认没有激活的 芝麻开们:http://pan.bai ...
- Mysql 索引实现原理. 聚集索引, 非聚集索引
Mysql索引实现: B-tree,B是balance,一般用于数据库的索引.使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度.而B+tree是B-tree的一个变种,My ...
- asp.net mvc短信接口调用——阿里大于API开发心得
互联网上有许多公司提供短信接口服务,诸如网易云信.阿里大于等等.我在自己项目里需要使用到短信服务起到通知作用,实际开发周期三天,完成配置.开发和使用,总的说,阿里大于提供的接口易于开发,非常的方便,短 ...
- 解决:笔记本安装mint18时,安装界面显示不全
近日在给自己的笔记本安装mint18时,安装界面显示不全,就是安装时到了分区界面后看不到下一步. 很无奈.... 于是胡乱摸索,得到解决的办法. 按住键盘上的ALT键,用鼠标向上拖动安装的界面,最好是 ...
- 解决:error: Cannot fetch repo (TypeError: expected string or buffer)
同步源码,问题重现: Fetching project platform/external/libopus Fetching project repo error: Cannot fetch repo ...
- Linux--目录结构解释(转)
/ root --- 启动Linux时使用的一些核心文件.如操作系统内核.引导程序Grub等. home --- 存储普通用户的个人文件 ftp --- 用户所有服务 httpd samba user ...
- 江太公:javascript count(a)(b)(c)(d)运行过程思考
昨天,我弟抛给我一个js的题,使用类似标题那样的调用方法计算a*b*c*d以致无穷的实现方法.思考了半天,终于理清了它的运行过程,记录于下: 函数体: <!DOCTYPE html> &l ...
- php-fpm中启用慢日志配置(用于检测执行较慢的PHP脚本)
虽然通过nginx accesslog可以记录用户访问某个接口或者网页所消耗的时间,但是不能清晰地追踪到具体哪个位置或者说函数慢,所以通过php-fpm慢日志,slowlog设置可以让我们很好的看见哪 ...
- OverWatch团队文档格式规范
V1.0 最终修改于2016/10/19 概述 软件工程中,一份优雅的文档不仅能降低团队成员之间的沟通难度,而且能给之后的开发者提供一个非常有效的引导.本团队为了规范整个项目中文档的格式,便于统一管理 ...
- 使用.NET实现断点续传
http://www.cnblogs.com/goody9807/archive/2007/06/05/772501.html 断点续传的原理在了解HTTP断点续传的原理之前,先来说说HTTP协议,H ...