4. 创建.NET客户端

使用浏览器调用服务是处理测试的一种简单方法。客户端常常使用JavaScript(这是JSON的优点)和.NET客户端。下面创建一个Console App(.NET Core)项目来调用服务。

BookServiceClientApp的示例代码使用了以下依赖项和名称空间:

依赖项

Microsoft.Extensions.DependencyInjection

Microsoft.Extensions.Loggingh.Console

Newtonsoft.Json

名称空间

Microsoft.Extensions.Logging

Newtonsoft.Json

System

System.Collections.Generic

System.Linq

System.Net.Http

System.Net.Http.Headers

System.Runtime.CompilerServices

System.Text

System.Threading.Tasks

System.Xml.Linq

1. 发送GET请求

要发送HTTP请求,应使用HttpClient类。在本章中,HttpClient类用来发送不同的HTTP请求。要使用HttpClient类,需要添加NuGet包System.Net.Http,打开名称空间System.Net.Http。要将JSON数据转换为.NET类型,应添加NuGet包Newtonsoft.Json。

为了把需要的所有URL放在一个地方,UrlService类为需要的URL定义了属性:

    public class UrlService
    {
        public string BaseAddress => "https://localhost:5001";
        public string BookaPI => "api/BookChapters/";
    }

注意:

需要将UrlService类中的BaseAddress更改为服务的主机和端口号。当启动服务主机时,可以在浏览器中看到端口号。

在示例项目中,泛型类HttpClientService创建为对于不同的数据类型只有一种实现方式。构造函数需要通过DI获得UrlService,使用从UrlService中检索的基地址创建HttpClient:

    public class HttpClientService<T>:IDisposable where T:class
    {
        private HttpClient _httpClient;
        private readonly UrlService _urlService;
        private readonly ILogger<HttpClientService<T>> _logger;
        public HttpClientService(UrlService urlService,ILogger<HttpClientService<T>> logger)
        {
            _urlService = urlService ?? throw new ArgumentNullException(nameof(urlService));
            _logger = logger ??throw new ArgumentNullException(nameof(logger));
            _httpClient = new HttpClient();
            _httpClient.BaseAddress = new Uri(urlService.BaseAddress);
        }

        public void Dispose()
        {
            _httpClient.Dispose();
        }
    }

注意:

在示例代码中,ILogger接口用于向控制台写入日志信息。

方法GetInternalAsync发出一个GET请求来接收一组项。该方法调用HttpClient的GetAsync方法来发送GET请求。HttpResponseMessage包含收到的信息。响应的状态码写入控制台来显示结果。如果服务器返回一个错误,则GetAsync方法不抛出异常。异常在方法EnsureSuccessStatus中抛出,该方法在返回的HttpResponseMessage实例上调用。如果HTTP状态码是错误类型,该方法就抛出一个异常。响应体包含返回的JSON数据。这个JSON信息读取为字符串并返回:

        private async Task<string> GetInternalAsync(string requestUri)
        {
            if (string.IsNullOrEmpty(requestUri))
            {
                throw new ArgumentNullException(nameof(requestUri));
            }
            if (_objectDisposed)
            {
                throw new ObjectDisposedException(nameof(_httpClient));
            }
            HttpResponseMessage resp = await _httpClient.GetAsync(requestUri);
            LogInformation($"status from GET {resp.StatusCode}");
            resp.EnsureSuccessStatusCode();
            return await resp.Content.ReadAsStringAsync();
        }
        private void LogInformation(string message,[CallerMemberName]string callerName = null)
        {
            _logger.LogInformation($"{nameof(HttpClientService<T>)}.{callerName}: {message}");
        }

服务器控制器用GET请求定义了两个方法:一个方法返回所有章,另一个方法只返回一个章。但是需要章的标识符和URL。方法GetAllAsync调用GetInternalAsync方法,把返回的JSON信息转换为一个集合,而方法GetAsync将结果转换成单个项这些方法声明为虚拟的,允许在派生类中重写它们:

        public async virtual Task<T> GetAsync(string requestUri)
        {
            if (string.IsNullOrEmpty(requestUri))
            {
                throw new ArgumentNullException(requestUri);
            }
            string json = await GetInternalAsync(requestUri);
            return JsonConvert.DeserializeObject<T>(json);
        }
        public async virtual Task<IEnumerable<T>> GetAllAsync(string requestUri)
        {
            if (string.IsNullOrEmpty(requestUri))
            {
                throw new ArgumentNullException(nameof(requestUri));
            }
            string json = await GetInternalAsync(requestUri);
            return JsonConvert.DeserializeObject<IEnumerable<T>>(json);
        }

在客户端代码中不使用泛型类HttpClien

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值