你好呀~欢迎关注微信公众号:python入门到放弃

在aspNetCore请求第三方Api

.NetCore admin 554浏览

在aspNetCore请求第三方Api

HttpClient简介在Core使用HttpClient类型化服务使用refit框架来请求Api使用DelegatingHandler拦截请求

HttpClient简介

在Core中一般推荐使用HttpClient来请求第三方Api,他是一个高度可扩展的请求库。内部类似Core中的中间件,可以根据自己的需求来进行拦截,处理。
关于HttpClient的基础知识可参考文章:c#中HttpClient的使用

在Core使用HttpClient

一、使用HttpClient工厂(IHttpClientFactory)
以该接口为例:

接口示例
接口示例

Query参数均不是必须参数,暂时不用管。但是头信息Host必须添加为api.apiopen.top
在CoreMvc中代码如下:
1、在Startup类中添加依赖注入:

        public void ConfigureServices(IServiceCollection services)
        
{
            services.AddHttpClient();
            services.AddControllersWithViews();
        }

2、根据返回的消息定义实体类

    public class getImagesModel<T>
    {
        public int Code { getset; }
        public string Message { getset; }
        public IEnumerable<T> result { getset; }
    }
    public class imageModel
    {
        public int id { getset; }
        public string time { getset; }
        public string img { getset; }
    }

3、在控制器中发送请求

private readonly IHttpClientFactory _clientFactory;
        public TestController(IHttpClientFactory clientFactory)
        
{
            _clientFactory = clientFactory;
        }
        public async Task<IActionResult> GetImage()
        
{
            IEnumerable<imageModel> imageModels = Array.Empty<imageModel>();
            HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, "https://www.apiopen.top/getImages");
            httpRequest.Headers.Add("host""api.apiopen.top");
            //创建HttpCilent
            var client = _clientFactory.CreateClient();
            var result = await client.SendAsync(httpRequest);
            var model = await result.Content.ReadAsAsync<getImagesModel<imageModel>>();
            imageModels = model.result;
            return View(imageModels);
        }

注*:其中ReadAsAsync方法需要安装包 install-package Microsoft.AspNet.WebApi.Client
4、添加一个视图模型为imageModel的list模型即可。
运行就可以看到如下:

imageModel展示列表
imageModel展示列表

可以看到信息显示是没有问题的,如果请求的接口很对,并且主机都是一样的,默认添加的请求头也是必须的,为了减少重复代码,还可以这样写:
这样注入:

public void ConfigureServices(IServiceCollection services)
        
{
            //services.AddHttpClient();
            // 参数1为自定义名称
            services.AddHttpClient("apiopen", client =>
            {
                client.BaseAddress = new Uri("https://www.apiopen.top");
                client.DefaultRequestHeaders.Add("host""api.apiopen.top");
            });
            services.AddControllersWithViews();
        }

控制器中:

private readonly IHttpClientFactory _clientFactory;
        public TestController(IHttpClientFactory clientFactory)
        
{
            _clientFactory = clientFactory;
        }
        public async Task<IActionResult> GetImage()
        
{
            IEnumerable<imageModel> imageModels = Array.Empty<imageModel>();
            HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, "/getImages");
            //HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, "https://www.apiopen.top/getImages");
            //httpRequest.Headers.Add("host", "api.apiopen.top");
            //创建HttpCilent
            var client = _clientFactory.CreateClient("apiopen");
            //var client = _clientFactory.CreateClient();
            var result = await client.SendAsync(httpRequest);
            var model = await result.Content.ReadAsAsync<getImagesModel<imageModel>>();
            imageModels = model.result;
            return View(imageModels);
        }

类型化服务

同样的是上面的接口换一种方式。
1、创建一个服务类如下:

public class GetImagesService
    {
        private HttpClient _client;
        public GetImagesService(HttpClient client)
        
{
            client.BaseAddress = new Uri("https://www.apiopen.top");
            client.DefaultRequestHeaders.Add("host""api.apiopen.top");
            _client = client;
        }
        public async Task<IEnumerable<imageModel>> GetImages()
        {
            HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, "/getImages");
            var result = await _client.SendAsync(httpRequest);
            var data = await result.Content.ReadAsAsync<getImagesModel<imageModel>>();
            return data.result;
        }
    }

2、这Startup中这样注入:

public void ConfigureServices(IServiceCollection services)
        
{
            //services.AddHttpClient();
            services.AddHttpClient("apiopen", client =>
            {
                client.BaseAddress = new Uri("https://www.apiopen.top");
                client.DefaultRequestHeaders.Add("host""api.apiopen.top");
            });

            //注册类型化服务
            services.AddHttpClient("apiopen2").AddTypedClient<GetImagesService>();
            services.AddControllersWithViews();
        }

3、控制器

public async Task<IActionResult> GetImage1([FromServices]GetImagesService service)
        
{
            IEnumerable<imageModel> imageModels = Array.Empty<imageModel>();
            imageModels = await service.GetImages();
            return View("GetImage", imageModels);
        }

即可。

使用refit框架来请求Api

Refit 是一个类型安全的 REST 开源库,是一套基于 RESTful 架构的 .NET 客户端实现,内部使用 HttpClient 类封装,可通过 Refit 更加简单安全地访问Web API 接口,使用该框架,我们只需要定义该接口的原型即可。
还是上面的接口来简单示例:
1、安装refit包
Install-Package refit
2、创建一个接口类

using Refit;
// ...
public interface GetImageForRefit
    {
        [Post("/getImages")]
        Task<getImagesModel<imageModel>> GetImagesByRefit();
    }

3、注入

public void ConfigureServices(IServiceCollection services)
        {
            //services.AddHttpClient();
            services.AddHttpClient("apiopen", client =>
            {
                client.BaseAddress = new Uri("https://www.apiopen.top");
                client.DefaultRequestHeaders.Add("host""api.apiopen.top");
            });

            services.AddHttpClient("apiopen2").AddTypedClient<GetImagesService>();
            // 使用refit矿建请求api
            services.AddHttpClient("apiopen3", client =>
            {
                client.BaseAddress = new Uri("https://www.apiopen.top");
                client.DefaultRequestHeaders.Add("host""api.apiopen.top");
            }).AddTypedClient(client=>RestService.For<IGetImageForRefit>(client));
            services.AddControllersWithViews();
        }

4、控制器

public async Task<IActionResult> GetImageByrefit([FromServices]IGetImageForRefit serviceByrefit)
        
{
            IEnumerable<imageModel> imageModels = Array.Empty<imageModel>();
            var data = await serviceByrefit.GetImagesByRefit();
            imageModels = data.result;
            return View("GetImage", imageModels);
        }

使用DelegatingHandler拦截请求

在简介中可以知道他是像中间件一样的。
下面实现在请求头中必须含有key
1、添加一个类继承自DelegatingHandler

public class ValidataHandlerDelegatingHandler
    {
        protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        
{
            if (!request.Headers.Contains("key"))
            {
                return new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    // 这里返回文本,在不头部不添加key时,读取对象会报错。
                    Content = new StringContent("错误")
                };
            }
            return await base.SendAsync(request, cancellationToken);
        }
    }

2、依赖注入中注入即可

services.AddSingleton<ValidataHandler>();
            services.AddHttpClient("handler", client =>
            {
                client.BaseAddress = new Uri("https://www.apiopen.top");
                client.DefaultRequestHeaders.Add("host""api.apiopen.top");

            }).AddHttpMessageHandler<ValidataHandler>();

转载请注明: 十三 » 在aspNetCore请求第三方Api

喜欢 (0) or 分享 ( 0)