创建和调用webapi接口服务文件

前言 

源码地址:https://github.com/kmonkey9006/QuickWebApi

 现在项目中用的是webapi,其中有以下问题:

      1.接口随着开发的增多逐渐增加相当庞大。

    2.接口调用时不好管理。

  以上是主要问题,对此就衍生了一个想法:

    如果每一个接口都一个配置文件来管理,每个配置文件能清晰表示处理接口文件,地址,参数,返回值,那么通过这个配置文件,就能很好的管理起来我们所有的webapi接口不是吗?

有了这个思路之后就有了以下的实现:

具体实现:

1.核心代码

 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);
                    }
                }
            }
            return new result<tresp>(-1, "未能找到合适的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();

                    for (int i = 0; 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());
                    }
                }
            }
            return new result<tresp>(-1, "未能找到合适的api定义");
        }
    }

  public class webapi<T> : webapi<T, object>
    {
        public webapi() { }
        public webapi(string service_prefix)
            : base(service_prefix)
        { }
        public webapi(long service_prefix_id)
            : base(service_prefix_id)
        { }
    }

  public void Build_Apis()
        {
            foreach (var ass in AppDomain.CurrentDomain.GetAssemblies().Where(a => a.GetCustomAttributes(typeof(QuickWebApiDllAttribute), true).Length > 0))
            {
                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);
            }
        }

  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);
                if (_apis == null || _apis.Count == 0) 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.1:其中Build_Apis()方法,是系统根据,webapi接口描述,创建的对应的接口服务配置文件操作。

配置如下:

生成接口文件如下:

接口的实现

接下来只需你把xml文件引用到你要调用的站点下即可。

1.2:其中Load_Apis()方式是在程序启动时加载webapi服务配置文件的操作,在这不再累述。

1.3:其中  result<tresp> _invoke(Expression exp, params object[] args)方式是:通过lambda对传递过来的委托,进行相应的反射操作。

其中委托定义如下:

namespace QuickWebApi
{
    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();
    //public delegate IHttpActionResult apiaction_s<treq>(treq data) where treq : struct;
}

注:目前delegate只支持三个参数以内的接口(且参数类型目前仅支持int,long,string),如果参数不符合条件可传递对象。

以上为具体实现至于有不了解的可以在文章顶部下载代码也可以,点击公共中qq与我联系。

下面我来写一下它的使用:

1.初始化:

在global中添加如下代码:

2.在mvc中调用:

时间: 2024-11-03 03:47:51

创建和调用webapi接口服务文件的相关文章

利用委托与Lambada创建和调用webapi接口(含源码)

前言 前不久有对此做过一次总结.但是不够详细,今天整理重发一次. 现在项目中用的是webapi,其中有以下问题:    1.接口随着开发的增多逐渐增加相当庞大. 2.接口调用时不好管理. 以上是主要问题,对此就衍生了一个想法: 如果每一个接口都一个配置文件来管理,每个配置文件能清晰表示处理接口文件,地址,参数,返回值,那么通过这个配置文件,就能很好的管理起来我们所有的webapi接口不是吗? 有了这个思路之后就有了以下的实现: 1.具体实现: public void Build_Apis() {

php中创建和调用webservice接口示例

这篇文章主要介绍了php中创建和调用webservice接口示例,包括webservice基本知识.webservice服务端例子.webservice客户端例子,需要的朋友可以参考下 作为开发者来讲,要想写webservice接口或者调用别人的webservice接口,首先需要了解什么是webservice.简单说, WebService就是一些站点开放一些服务出来, 也可以是你自己开发的Service, 也就是一些方法, 通过URL,指定某一个方法名,发出请求,站点里的这个服务(方法),接到

如何使用程序调用webApi接口

如何使用程序调用webApi接口 在C#中,传统调用HTTP接口一般有两种办法: WebRequest/WebResponse组合的方法调用 WebClient类进行调用. 第一种方法抽象程度较低,使用较为繁琐:而WebClient主要面向了WEB网页场景,在模拟Web操作时使用较为方便,但用在RestFul场景下却比较麻烦,在Web API发布的同时,.NET提供了两个程序集:System.Net.Http和System.Net.Http.Formatting.这两个程序集中最核心的类是Htt

调用URL 接口服务

1.Net调用URL 接口服务 using System; using System.Collections; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.W

WebApi接口 - 如何在应用中调用webapi接口

简单做个webapi(查询+添加)接口 首先,我们需要有一个webapi接口项目,我这里以前面WebApi接口 - 响应输出xml和json文章的项目来构建本篇文章的测试用例:这里新建一个 DbData 数据源类,主要用来做数据存储和提供查询列表数据及添加数据方法,具体代码如:  1 public class DbData 2     { 3         public static DbData Current 4         { 5             get 6         

小程序调用后端接口服务 配置文件详解

前言:为了开发阶段的效率更高,方便项目接口管理,在做web项目时,我们需要把后端提供的接口地址进行配置,这样我们自己在调用时,要方便得多,利己利人.在配置小程序接口地址时,和web的配置大同小异,下面总结几点配置小程序接口地址的思路: 1.所有接口地址,要丢在一个对象里[为了方便下面解释,这里设置一个对象名:config],为什么了,因为要对外暴露,方便外部访问,这样[key:value]方式是最合理的,那就是对象了. 2.真实接口地址,也就是对象键值对的value,要用英文模式下Tab键的上一

调用WebAPI接口

[HttpPost]          接口public string Post([FromBody] string bjbh)         { var dwgc = new object(); string output = string.Empty; string msg = string.Empty; bool result = true; string errorCode = "200"; try { var dwgcbybjbhlist = db.Base_GetDwgc

控制台+Owin搭建WebAPI接口服务

当没有iis环境.想快速启动几个api接口测试又觉得新建一个api项目麻烦?来使用控制台做宿主,快速改几个api测试吧! 1.新建控制台项目 2.安装以下相关依赖 Microsoft.AspNet.WebApi Microsoft.AspNet.WebApi.Owin Microsoft.Owin.Hosting Microsoft.Owin.Host.HttpListener 3.新建API控制器,需要注意一下几点约定 >控制器放在文件夹Controllers下(没有新建一个) >控制器继承

java程序调用.net接口服务地址的写法

参考文章:http://download.csdn.net/detail/davidiao/7424767 http://www.cnblogs.com/mq0036/p/3554002.html .asmx?wsdl 注意:?wsdl 一定要加上,否则会报错.