利用委托与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也是很常用的 ...
随机推荐
- golang---文件读写
func Create(name string) (file *File, err error) 直接通过纹面创建文件 func NewFile(fd uintptr, name string) *F ...
- 传说中的inside番——“黄金圣衣”篇
10月21日,在今天的课堂上拿到了我们软工实践课程的战斗圣衣,传说穿上它就能够在编码意志上+100,有着爆种.不死不休战斗等传奇属性——build to win.当然,这是我的追求与梦想.现在的我,还 ...
- NB實體連線到公司的網路,無法上網解決方案,需設 proxy。
未使用 VPN Cisco Anyconnect 已連線到公司的網路: google-chrome-stable --proxy-server="proxy.XXXcomm.com:3128 ...
- 更好的pip工作流
转自:http://codingpy.com/article/a-better-pip-workflow-recommended-by-kenneth/ 现在大家开发Python应用时,在代码库的根目 ...
- js限制输入框只能输入数字
分享下js限制输入框中只能输入数字的方法,包括整数与小数,分享几个例子,有需要的朋友参考下. 1.使用正则表达式限制输入框只能输入数字: <input type="text" ...
- 【USACO 2.4】The Tamworth Two
题意:C代表cows,F代表farmer,一开始都向北,每分钟前进1步,如果前方不能走,则这分钟顺时针转90°,问多少步能相遇,或者是否不可能相遇,10*10的地图. 题解:dfs,记录状态,C和F的 ...
- chkdsk磁盘修复命令工具怎么用,怎样运行chkdsk工具修复?
Chkdsk是系统检查磁盘当前状态的一个命令,启动它可以显示磁盘状态.内存状态和指定路径下指定文件的不连续数目.选择“开始→运行”输入“Chkdsk”回车,即可启动Chkdsk,它会自动校验文件并将丢 ...
- 区间第K大(一)
Problem: 给定无序序列S:[b, e),求S中第K大的元素. Solution 1.裸排序 2.现将区间均分成两段,S1, S2,对S1,S2分别排序,然后
- 利用chorme调试手机网页
太方便了,很实用的技巧(特意记录一下) 1.pc端安装最新的chrome 2.手机端安装最新的chrome ( Android机 ) 3.USB连接线 4.打开电脑的chrome 在地址栏输入 chr ...
- iOS - 适配器模式场景总结
适配器模式: 1.出现场景 TableViewCell视图层 - 输出 无论NSData怎么变化,数据都可以显示在视图层中. 2.组成结构 输入 - [适配器]- 输出 (数据层) - [适配器]- ...