WebApiClient.JIT (提取码:ghuc):一个基于HttpClient的开源项目。您只需要定义c#接口并修改相关功能即可异步调用远程http接口的客户端库。
nuget上搜索WebApiClient.JIT,net和core都支持
作者的事例类
using Demo.HttpClients; using Demo.HttpServices; using System; using System.Threading; using System.Threading.Tasks; using WebApiClient; using WebApiClient.Parameterables; namespace Demo { class Program { static void Main(string[] args) { Init(); RequestAsync().Wait(); Console.ReadLine(); } /// <summary> /// 初始化配置 /// </summary> static void Init() { HttpServer.Start(9999); // 注册IUserApi 配置其工厂 HttpApi.Register<IUserApi>().ConfigureHttpApiConfig(c => { c.HttpHost = new Uri("http://localhost:9999/"); c.FormatOptions.DateTimeFormat = DateTimeFormats.ISO8601_WithMillisecond; }); } /// <summary> /// 请求接口 /// </summary> /// <returns></returns> private static async Task RequestAsync() { var userApi = HttpApi.Resolve<IUserApi>(); var user = new UserInfo { Account = "laojiu", Password = "123456", BirthDay = DateTime.Parse("2018-01-01 12:30:30"), Email = "laojiu@webapiclient.com", Gender = Gender.Male }; var about = await userApi .GetAboutAsync("webapi/user/about", user, "somevalue"); var aboutCache = await userApi .GetAboutAsync("webapi/user/about", user, "somevalue"); var user1 = await userApi .GetByIdAsync("id001", CancellationToken.None); var user2 = await userApi .GetByAccountAsync("laojiu", CancellationToken.None); var user3 = await userApi .UpdateWithFormAsync(user, nickName: "老九", age: 18) .Retry(3, i => TimeSpan.FromSeconds(i)) .WhenCatch<HttpStatusFailureException>(); var user4 = await userApi .UpdateWithJsonAsync(user); var user5 = await userApi .UpdateWithXmlAsync(user).HandleAsDefaultWhenException(); var file = new MulitpartFile("file.data"); file.UploadProgressChanged += (s, e) => { // Console.WriteLine(e.Progress); }; var user6 = await userApi .UpdateWithMulitpartAsync(user, "老九", 18, file); } } }
using System.ComponentModel.DataAnnotations; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using WebApiClient; using WebApiClient.Attributes; using WebApiClient.Parameterables; namespace Demo.HttpClients { /// <summary> /// 用户操作接口 /// </summary> [TraceFilter(OutputTarget = OutputTarget.Console | OutputTarget.Debug)] [HttpHost("http://localhost:9999/")] // HttpHost可以在Config传入覆盖 public interface IUserApi : IHttpApi { // GET {url}?account={account}&password={password}&something={something} [HttpGet] [Cache(10 * 1000)] Task<string> GetAboutAsync( [Uri] string url, UserInfo user, string something); // /GET webapi/user/GetById?id=id001 // Return HttpResponseMessage [HttpGet("webapi/user/GetById/{id}")] [BasicAuth("userName", "password")] [Timeout(10 * 1000)] // 10s超时 ITask<HttpResponseMessage> GetByIdAsync( [Required]string id, CancellationToken token); // GET webapi/user/GetByAccount?account=laojiu // Return 原始string内容 [HttpGet("webapi/user/GetByAccount")] ITask<string> GetByAccountAsync( [Required]string account, CancellationToken token); // POST webapi/user/UpdateWithForm // Body Account=laojiu&Password=123456&name=value&nickName=老九&age=18 // Return json或xml内容 [HttpPost("webapi/user/UpdateWithForm")] [FormField("name", "value")] // 固定的参数值可以这么写 ITask<UserInfo> UpdateWithFormAsync( [FormContent, Required] UserInfo user, [FormField] string nickName, [FormField, Range(1, 100)] int? age); // POST webapi/user/UpdateWithJson // Body {"Account":"laojiu","Password":"123456"} // Return json或xml内容 [HttpPost("webapi/user/UpdateWithJson")] ITask<UserInfo> UpdateWithJsonAsync( [JsonContent, Required] UserInfo user); // POST webapi/user/UpdateWithXml // Body <?xml version="1.0" encoding="utf-8"?><UserInfo><Account>laojiu</Account><Password>123456</Password></UserInfo> // Return xml内容 [HttpPost("webapi/user/UpdateWithXml")] ITask<UserInfo> UpdateWithXmlAsync( [XmlContent, Required] UserInfo user); // POST webapi/user/UpdateWithMulitpart // Body multipart/form-data // Return json或xml内容 [HttpPost("webapi/user/UpdateWithMulitpart")] ITask<UserInfo> UpdateWithMulitpartAsync( [MulitpartContent, Required] UserInfo user, [MulitpartText] string nickName, [MulitpartText] int age, MulitpartFile file); /// <summary> /// 下载文件 /// </summary> /// <param name="uri">文件相对或绝对路径</param> /// <returns></returns> [HttpGet] [TraceFilter(TraceResponse = false)] ITask<HttpResponseFile> DownloadFileAsync([Uri, Required] string uri); } }
自己做的测试
using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web.Script.Serialization; using WebApiClient; namespace ConsoleApp1 { public class Program { static void Main(string[] args) { Init(); RequestAsync().Wait(); Console.ReadLine(); } /// <summary> /// 初始化配置 /// </summary> static void Init() { HttpServer.Start(9999); // 注册IUserApi 配置其工厂 HttpApi.Register<IUserApi>().ConfigureHttpApiConfig(c => { c.HttpHost = new Uri("http://localhost:42926/"); c.FormatOptions.DateTimeFormat = DateTimeFormats.ISO8601_WithMillisecond; c.GlobalFilters.Add(new ApiTokenFilter(""));//添加Hearder }); } /// <summary> /// 请求接口 /// </summary> /// <returns></returns> private static async Task RequestAsync() { var userApi = HttpApi.Resolve<IUserApi>(); string value = "{\"name\":\"1\",\"id\":\"2\"}"; var about = await userApi .GetAboutAsync("api/Test/GetValue", value); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WebApiClient; using WebApiClient.Attributes; namespace ConsoleApp1 { [TraceFilter(OutputTarget = OutputTarget.Console | OutputTarget.Debug)] [HttpHost("http://localhost:9999/")] // HttpHost可以在Config传入覆盖 public interface IUserApi : IHttpApi { [HttpGet] [Cache(10 * 1000)] //[Header("Authorization", "Basic 11111")] Task<string> GetAboutAsync( [Uri] string url, string value); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WebApiClient; using WebApiClient.Contexts; namespace ConsoleApp1 { class ApiTokenFilter : IApiActionFilter { private string token { get; set; } public ApiTokenFilter(string token) { this.token = token; } public Task OnBeginRequestAsync(ApiActionContext context) { context.RequestMessage.Headers.Add("Authorization", $"Basic {token}"); return Task.FromResult<object>(null); } public Task OnEndRequestAsync(ApiActionContext context) { return Task.FromResult<object>(null); } } }