利用委托与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也是很常用的 ...
随机推荐
- zabbix告警使用sendEmail
1sendmail介绍 详细介绍见官网:http://caspian.dotconf.net/menu/Software/SendEmail/ 2使用sendEmail sendEmail是个十分优秀 ...
- C#-WebForm-WebForm开发基础、如何给控件注册事件?——事件委托写法、http无状态性、三层结构
(小知识 - xml:可扩展的标记语言 html:超文本标记语言) 一.创建WebForm:新建→网站 此时文件夹中只有一个 config 文件,打开后 二.在项目下右键添加新项 在设计页面中打开 从 ...
- 【caffe】绘制网络结构图
@tags caffe 网络结构 可视化 当拿到一份网络定义文件net.prototxt,可以用工具画出网络结构.最快速的方法是使用在线工具netscope,粘贴内容后shift+回车就可以看结果了. ...
- 使用Swift打造动态库SDK和DemoAPP时所遇到的(Xcode7.3)
使用Swift开发SDK的优点是,生成的SDK对于Obj-C或是Swift调用都不需要自己去建桥接文件,因为Swift的SDK打包时默认已经自动生成供OC调用的.h文件.OC调用时直接import,s ...
- 【CityHunter】基于LBS的AR体感游戏设计理念
本人目前还不是游戏行业的圈内人士,并不懂得,游戏行业的生态圈,也不懂得,所谓的什么“中国市场环境”.所以不敢发表关于这方面的见解,不过我在这里想要插一句话,就是我认为啊,行业内,人与人之间还是有分层次 ...
- Linux(Centos6.5)用户名密码
用户列表文件:/etc/passwd用户组列表文件:/etc/group 查看系统中有哪些用户:cut -d : -f 1 /etc/passwd查看可以登录系统的用户:cat /etc/passwd ...
- mysql常用操作语句
mysql常用操作语句 1.mysql -u root -p 2.mysql -h localhost -u root -p database_name 2.列出数据库: 1.show datab ...
- C#中精确计时的一点收获 【转】
C#中精确计时的一点收获 [转] 以下所有代码运行环境:Windows 2003, Intel(R) Core(TM) 2 Duo CPU E8400 @ 3.00GHz 2.99GHz,2.96G ...
- APP的消息推送(极光推送)
APP的消息推送,使用的第三方平台是极光推送 简单案例(以Thinkphp为例): 1.下载下载PHPSDK 2.把PHPSDK目录下的jpush-api-php-client-3.5.1\src\J ...
- EF 增删改
一.新增 UserInfo user = new UserInfo() { UserName = "jamsebing", UserPass = " }; db.User ...