zoukankan      html  css  js  c++  java
  • .NET Core 使用 WebApiClient.JIT 调用第三方接口

    开始前首先通过 NuGet 引入包,当前使用版本为 v1.0.9,发布日期 2019年5月21日

    Github:https://github.com/dotnetcore/WebApiClient/tree/WebApiClient.JITAOT  注意底部有Wiki文档对使用非常有帮助,请仔细阅读。

    1.新建 xxxHttpsModule 并在 Startup ConfigureServices 中注入。(单独新建 HttpsModule 是为了将不同的业务分离)

    public static class xxxHttpsModule
    {
        public static IServiceCollection Register(IServiceCollection services, IConfigurationRoot appConfiguration)
        {
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    
            void config(HttpApiConfig c)
            {
                c.HttpHost = new Uri(appConfiguration["Server:Url"]);//AppSettings.json 中的服务器地址
                c.GlobalFilters.Add(new DefaultHeaderAttribute(appConfiguration));
            }
    
            services.AddHttpApi<IxxxApi>().ConfigureHttpApiConfig(config);//注入接口
    
            return services;
        }
    }
    

    AddHttpApi 是一个扩展方法,这样写只是为了在多次使用时,看起来更协调。

    /// <summary>
    /// 基于DependencyInjection的扩展
    /// </summary>
    public static class DependencyInjectionExtensions
    {
        /// <summary>
        /// 添加HttpApi
        /// 返回HttpApi工厂
        /// </summary>
        /// <typeparam name="TInterface">接口类型</typeparam>
        /// <param name="services"></param>
        /// <returns></returns>
        public static HttpApiFactoryBuilder<TInterface> AddHttpApi<TInterface>(this IServiceCollection services)
            where TInterface : class, IHttpApi
        {
            return new HttpApiFactoryBuilder<TInterface>(services);
        }
    }
    

    IxxxApi 接口中的内容就是第三方接口的内容

    [TraceFilter(OutputTarget = OutputTarget.Console)]//这个设置可以将日志输入到控制台
    public interface IxxxApi : IHttpApi
    {
        /// <summary>
        /// 创建xxx信息
        /// </summary>
        /// <param name="input">实体</param>
        /// <returns></returns>
        [Timeout(10000)]
        [HttpPost("/api/v2/x/xxx")]
        ITask<AjaxResponse<List<xxxApiDto>>> GetxxxPagedList([JsonContent] xxxDto input);
    
        /// <summary>
        /// 获取xxx信息
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <returns></returns>
        [Timeout(10000)]
        [HttpGet("/api/v2/x/xxx")]
        ITask<AjaxResponse<List<xxxApiDto>>> GetxxxPagedList(int pageIndex);
    }

    2.创建 HttpApi 实例工厂创建器类,具体内容如下。目前没有修改过里面的内容。

    using System;
    using WebApiClient;
    using System.Net.Http;
    using Microsoft.Extensions.DependencyInjection;
    
    /// <summary>
    /// HttpApi实例工厂创建器
    /// </summary>
    /// <typeparam name="TInterface"></typeparam>
    public class HttpApiFactoryBuilder<TInterface> where TInterface : class, IHttpApi
    {
        private bool keepCookieContainer = true;
    
        private TimeSpan lifeTime = TimeSpan.FromMinutes(2d);
    
        private TimeSpan cleanupInterval = TimeSpan.FromSeconds(10d);
    
        private Action<HttpApiConfig, IServiceProvider> configOptions;
    
        private Func<IServiceProvider, HttpMessageHandler> handlerFactory;
    
    
        /// <summary>
        /// HttpApi实例工厂创建器
        /// </summary>
        /// <param name="services"></param>
        public HttpApiFactoryBuilder(IServiceCollection services)
        {
            services.AddSingleton<IHttpApiFactory<TInterface>, HttpApiFactory<TInterface>>(p =>
            {
                return new HttpApiFactory<TInterface>()
                    .SetLifetime(this.lifeTime)
                    .SetCleanupInterval(this.cleanupInterval)
                    .SetKeepCookieContainer(this.keepCookieContainer)
                    .ConfigureHttpMessageHandler(() => this.handlerFactory?.Invoke(p));
            });
    
            services.AddTransient(p =>
            {
                var factory = p.GetRequiredService<IHttpApiFactory<TInterface>>();
                factory.ConfigureHttpApiConfig(c =>
                {
                    c.ServiceProvider = p;
                    this.configOptions?.Invoke(c, p);
                });
                return factory.CreateHttpApi();
            });
        }
    
        /// <summary>
        /// 配置HttpApiConfig
        /// </summary>
        /// <param name="configOptions">配置选项</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        public HttpApiFactoryBuilder<TInterface> ConfigureHttpApiConfig(Action<HttpApiConfig> configOptions)
        {
            if (configOptions == null)
            {
                throw new ArgumentNullException(nameof(configOptions));
            }
            return this.ConfigureHttpApiConfig((c, p) => configOptions.Invoke(c));
        }
    
    
        /// <summary>
        /// 配置HttpApiConfig
        /// </summary>
        /// <param name="configOptions">配置选项</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        public HttpApiFactoryBuilder<TInterface> ConfigureHttpApiConfig(Action<HttpApiConfig, IServiceProvider> configOptions)
        {
            this.configOptions = configOptions ?? throw new ArgumentNullException(nameof(configOptions));
            return this;
        }
    
        /// <summary>
        /// 配置HttpMessageHandler的创建
        /// </summary>
        /// <param name="handlerFactory">创建委托</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        public HttpApiFactoryBuilder<TInterface> ConfigureHttpMessageHandler(Func<HttpMessageHandler> handlerFactory)
        {
            if (handlerFactory == null)
            {
                throw new ArgumentNullException(nameof(handlerFactory));
            }
            return this.ConfigureHttpMessageHandler(p => handlerFactory.Invoke());
        }
    
        /// <summary>
        /// 配置HttpMessageHandler的创建
        /// </summary>
        /// <param name="handlerFactory">创建委托</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        public HttpApiFactoryBuilder<TInterface> ConfigureHttpMessageHandler(Func<IServiceProvider, HttpMessageHandler> handlerFactory)
        {
            this.handlerFactory = handlerFactory ?? throw new ArgumentNullException(nameof(handlerFactory));
            return this;
        }
    
        /// <summary>
        /// 置HttpApi实例的生命周期
        /// </summary>
        /// <param name="lifeTime">生命周期</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <returns></returns>
        public HttpApiFactoryBuilder<TInterface> SetLifetime(TimeSpan lifeTime)
        {
            if (lifeTime <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(lifeTime));
            }
            this.lifeTime = lifeTime;
            return this;
        }
    
    
        /// <summary>
        /// 获取或设置清理过期的HttpApi实例的时间间隔
        /// </summary>
        /// <param name="interval">时间间隔</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <returns></returns>
        public HttpApiFactoryBuilder<TInterface> SetCleanupInterval(TimeSpan interval)
        {
            if (interval <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(interval));
            }
            this.cleanupInterval = interval;
            return this;
        }
    
        /// <summary>
        /// 设置是否维护使用一个CookieContainer实例 该实例为首次创建时的CookieContainer
        /// </summary>
        /// <param name="keep">true维护使用一个CookieContainer实例</param>
        /// <returns></returns>
        public HttpApiFactoryBuilder<TInterface> SetKeepCookieContainer(bool keep)
        {
            this.keepCookieContainer = keep;
            return this;
        }
    }
    

    3.调用就和我们自己写的接口一样在构造函数中注入使用,如果不告诉你这是一个第三方接口,完全感觉不出来。

    4.WebApiClient 还可以通过 AliasAs 属性自定义字段名称

    
    [Serializable]
    public class xxxApiDto
    {
        /// <summary>
        /// 序列号
        /// </summary>
        [AliasAs("serialNum")]
        public string SerialNumber { get; set; }
    }

    目前发现如果在 xxxApiDto 类中属性存在类时, AliasAs 则不会被识别,目前的解决方案是使用 [JsonProperty(PropertyName = "serialNum")],再通过 JsonConvert.SerializeObject(xxx) 转换成 JSON 字符串。

    5.请求注入 Headers ,可以通过继承 ApiActionFilterAttribute 类,然后重写 OnBeginRequestAsync 实现。

  • 相关阅读:
    静态方法和类方法
    DEL: Restore Boxes after VirtualBox Upgrade
    DEL: IE "Your current security settings put your computer at risk. Click h
    EV: Using GitHub Repository
    EV: Windows Commands 命令
    EV: Notepad++ Regular Express syntax
    html页面的三个width: document, window, screen
    DEL: View web content zone in IE9
    EV: 关于min-width样式的使用
    EV: Linux Shell Commands
  • 原文地址:https://www.cnblogs.com/fxck/p/13076679.html
Copyright © 2011-2022 走看看