Preface

Now the project uses webapi, There are the following problems :

   1. With the increase of development, interfaces gradually increase, which is quite huge .

2. Interface calls are not easy to manage .

These are the main problems , There's an idea for that :

If every interface is managed by a configuration file , Each configuration file can clearly represent the processing interface file , Address , Parameters , Return value , So through this configuration file , We can manage all of our webapi Interface, isn't it ?

With this idea, we have the following implementation :

1. Concrete realization :

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()) ? " No default " : 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: among Build_Apis() Method , It's the system based on ,webapi Interface description , Create the corresponding interface service profile operation .

The configuration is as follows :

The generated interface file is as follows :

Interface implementation

Next, you just need to xml File reference to the site you want to call .

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: among Load_Apis() The way is to load it when the program starts webapi Operation of service configuration file , I won't repeat it here .

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);
}
}
}
, " Failed to find the right one api Definition ");
}
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());
}
}
}
, " Failed to find the right one api Definition ");
}
}

1.3: among   result<tresp> _invoke yes : adopt lambda The delegation passed on , Carry out the corresponding reflection operation .

The definition of delegation is as follows :

 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();

notes : at present delegate Only interfaces with less than three parameters are supported ( And the parameter type is currently only supported int,long,string), If the parameter does not meet the criteria, the object can be passed .

The above is the specific implementation, as for those who don't know, you can download the code at the top of the article , Click public qq Contact with me .

2. Now let me write about its use :

2.1. initialization :

stay global Add the following code to :

2.2. stay mvc Call in :

Using delegation and Lambada Create and call webapi More articles on interfaces

  1. WebApi Interface - How to call in application webapi Interface

    I'm glad to share it with you again webapi Interface related articles , This article will explain how to call in application. webapi Interface : For most of the friends who do internal management system and similar systems, they seldom call other people's interfaces , Therefore, there may be some confusion in this respect , Greek ...

  2. How to use program call webApi Interface

    How to use program call webApi Interface stay C# in , Traditional call HTTP There are generally two ways to interface : WebRequest/WebResponse Combined method calls WebClient Class . The first method is less abstract , send ...

  3. php Create and call webservice Interface example

    php Create and call webservice Interface example   This article mainly introduces php Create and call webservice Interface example , Include webservice Basic knowledge .webservice Server example .webservi ...

  4. aspx Page call webapi Interface error : The remote server returned an error :(500) Internal server error

    The code is running to response = (HttpWebResponse)request.GetResponse(); They started reporting errors reason : It may be because the interface called does not exist or there is an error in the interface , You can use postman Test connection ...

  5. 【C#】 Create and call webapi

    Two ,, Call through normal route ,, Path written to http://localhost:29920/api/Players  namely    Api/controller  until

  6. Use httpclient Asynchronous call WebAPI Interface

    Recent work needs to use Bot Framework Call the original WebAPI Query data , Find some ways , Most of them use HttpClient Called , The code is now posted for reference using System; using Sys ...

  7. Use HttpClient call WebAPI Interface , contain WebAPI End examples

    API End : using log4net; using System; using System.Collections.Generic; using System.IO; using System.L ...

  8. call WebAPI The interface address returns the serialized JSON All the attributes in the object have been added k__BackingField Keyword solutions

    1. Problem phenomenon : 2. The reason for this problem is that the returned result object entity has a serializable number  [Serializable]. Just remove it . 3. The effect of the solution :

  9. WebApi(6) backstage C# call WebApi

    https://www.cnblogs.com/cxd1008/p/6640015.html Let's write about backstage today C# How to access code webapi Use here HttpClient Method access webapi It's also very common ...

Random recommendation

  1. About the vs2010 Chinese compiler Qt When the project appears “ An external command that cannot be resolved ” Error of

    use Cmake speak Qt.VTK and ITK After integration , When you open a solution and add a new class, the run will appear “n Unresolved external commands ” Error of . The reason is that the new class failed to generate moc file , The solution is : 1. Right click To generate moc Of documents .h file , hit ...

  2. 20160326 javaweb Request forwarding and request inclusion

    (1) Request forwarding : this.getServletContext().getRequestDispatcher("").forward(request,response); requ ...

  3. C# Import text file into database

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windo ...

  4. Oracle Problem literal does not match format string

    problem : oerr ora 186101861, 00000, "literal does not match format string"// *Cause: Literals i ...

  5. CSS Initial understanding

    1. In the web page , html Responsible for the structure of a page css( Cascade table ) Is a data style in a web page 2. To write css Code mode : A: stay style Write code in tags , It can only be used in this page , Reusability is not strong . Format :<styl ...

  6. Spring And Akka Integration of

    summary In recent years, with the Spark The hot ,Spark Development language itself Scala. Distributed memory file system used Tachyon( Now renamed Alluxio) And based on Actor Research on concurrent programming model Akka It's got everybody's attention . ...

  7. android stuido Quick construction of code typesetting based on CTRL+ALT+L

    CTRL+ALT+L What should be paid attention to QQ In conflict with I will qq The shortcut to remove

  8. sql The understanding of the

    sql The function of : 1. Filter data , Connection table 2. Data supplement , Connection table 3. Data addition, subtraction, multiplication and division ,+ - * / 4. Logical transportation of data , such as case..when...,decode,nvl,ifnull.... ...

  9. php abstract Inherit polymorphic

    1. Inheritance and overloading !!!php Use in extends The method of single inheritance Inherited class   Parent class ( Base class ) A successor     Subclass ( Derived class ) If we need to overload the parent class method ( Methods cover ), Use a method name in a derived class that has the same name as the base class method ...

  10. switch case : stay JDK 7 in , And added the right String Type of support , No more writing If-Else To determine the string

    switch Of case Statement can be processed int,short,byte,char Type value , because short,byte,char Will be converted into int To deal with , This can also be seen from the generated bytecode . char a = 'e ...