博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET Core 下调用WebAPI
阅读量:4646 次
发布时间:2019-06-09

本文共 13118 字,大约阅读时间需要 43 分钟。

前言

今天我们介绍多种客户端调用WebApi的方式,可以是原生写的,也可以借助.NET 框架下的其他HTTP库。我们一起来看看它们之间的一些异同吧~

RestSharp

首先要介绍的就是这款REST 客户端,我们先来一起看看它的简介:

RestSharp 是一个基于 .NET 框架的 REST 客户端,RestSharp 是一个轻量的,不依赖任何第三方的组件或者类库的 HTTP 组件,RestSharp具有以下的优点:

01、支持.NET4.5.2+ 和 .NET Standard 2.0 平台

02、使用NuGet轻松安装开发包
03、自动 XML 和 JSON 反序列化
04、通过 ISerializer 和 IDeserializer 自定义序列化和反序列化为
05、模糊匹配元素名称 (例如:XML或JSON中的product_id将匹配名为ProductId的C#属性)
06、自动检测返回内容的类型
07、指出 GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE 和 COPY 请求,支持其它非标准 HTTP 方法
08、OAuth 1.0、OAuth 2.0、Basic、NTLM 和基于参数的身份认证
09、通过 IAuthenticator 接口自定义身份验证方案
10、支持异步操作

官方示例:

var client = new RestClient("https://www.xcode.me");// client.Authenticator = new HttpBasicAuthenticator(username, password);var request = new RestRequest("resource/{id}", Method.POST);request.AddParameter("name", "value"); // adds to POST or URL querystring based on Methodrequest.AddUrlSegment("id", "123"); // replaces matching token in request.Resource// add parameters for all properties on an objectrequest.AddObject(object);// or just whitelisted propertiesrequest.AddObject(object, "PersonId", "Name", ...);// easily add HTTP Headersrequest.AddHeader("header", "value");// add files to upload (works with compatible verbs)request.AddFile("file", path);// execute the requestIRestResponse response = client.Execute(request);var content = response.Content; // raw content as string// or automatically deserialize result// return content type is sniffed but can be explicitly set via RestClient.AddHandler();IRestResponse
response2 = client.Execute
(request);var name = response2.Data.Name;// or download and save file to diskclient.DownloadData(request).SaveAs(path);// easy async supportawait client.ExecuteAsync(request);// async with deserializationvar asyncHandle = client.ExecuteAsync
(request, response => { Console.WriteLine(response.Data.Name);});// abort the request on demandasyncHandle.Abort();

使用案例:

Setp 1

引入RestSharp包

Setp 2

新建一个API请求执行者的接口IRestSharp:

///     /// API请求执行者接口    ///     public interface IRestSharp    {        ///         /// 同步执行方法        ///         ///         /// 
IRestResponse Execute(IRestRequest request); /// /// 同步执行方法 /// ///
返回值
/// 请求参数 ///
T Execute
(IRestRequest request) where T : new(); ///
/// 异步执行方法 /// ///
请求参数 ///
///
RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action
callback); ///
/// 异步执行方法 /// ///
///
///
///
RestRequestAsyncHandle ExecuteAsync
(IRestRequest request, Action
> callback) where T : new(); }

 

Setp 3

新建一个实现类RestSharpClient,实现上述接口

///      /// Rest接口执行者     ///      public class RestSharpClient : IRestSharp     {         ///          /// 请求客户端         ///          private RestClient client;          ///          /// 接口基地址 格式:http://www.xxx.com/         ///          private string BaseUrl { get; set; }          ///          /// 默认的时间参数格式         ///          private string DefaultDateParameterFormat { get; set; }          ///          /// 默认验证器         ///          private IAuthenticator DefaultAuthenticator { get; set; }          ///          /// 构造函数         ///          ///          ///          public RestSharpClient(string baseUrl, IAuthenticator authenticator = null)         {             BaseUrl = baseUrl;             client = new RestClient(BaseUrl);             DefaultAuthenticator = authenticator;              //默认时间显示格式             DefaultDateParameterFormat = "yyyy-MM-dd HH:mm:ss";              //默认校验器             if (DefaultAuthenticator != null)             {                 client.Authenticator = DefaultAuthenticator;             }         }          ///          /// 通用执行方法         ///          /// 请求参数         /// 
/// 调用实例: /// var client = new RestSharpClient("http://localhost:82/"); /// var result = client.Execute(new RestRequest("api/values", Method.GET)); /// var content = result.Content;//返回的字符串数据 ///
///
public IRestResponse Execute(IRestRequest request) { request.DateFormat = string.IsNullOrEmpty(request.DateFormat) ? DefaultDateParameterFormat : request.DateFormat; var response = client.Execute(request); return response; } /// /// 同步执行方法 /// ///
返回的泛型对象
/// 请求参数 ///
/// var client = new RestSharpClient("http://localhost:82/"); /// var result = client.Execute
>(new RestRequest("api/values", Method.GET)); ///
///
public T Execute
(IRestRequest request) where T : new() { request.DateFormat = string.IsNullOrEmpty(request.DateFormat) ? DefaultDateParameterFormat : request.DateFormat; var response = client.Execute
(request); return response.Data; } ///
/// 异步执行方法 /// ///
请求参数 ///
回调函数 ///
/// 调用实例: /// var client = new RestSharpClient("http://localhost:62981/"); /// client.ExecuteAsync
>(new RestRequest("api/values", Method.GET), result => /// { /// var content = result.Content;//返回的字符串数据 /// }); ///
///
public RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action
callback) { request.DateFormat = string.IsNullOrEmpty(request.DateFormat) ? DefaultDateParameterFormat : request.DateFormat; return client.ExecuteAsync(request, callback); } ///
/// 异步执行方法 /// ///
返回的泛型对象
///
请求参数 ///
回调函数 ///
/// 调用实例: /// var client = new RestSharpClient("http://localhost:62981/"); /// client.ExecuteAsync
>(new RestRequest("api/values", Method.GET), result => /// { /// if (result.StatusCode != HttpStatusCode.OK) /// { /// return; /// } /// var data = result.Data;//返回数据 /// }); ///
///
public RestRequestAsyncHandle ExecuteAsync
(IRestRequest request, Action
> callback) where T : new() { request.DateFormat = string.IsNullOrEmpty(request.DateFormat) ? DefaultDateParameterFormat : request.DateFormat; return client.ExecuteAsync
(request, callback); } }

 Setp 4

新建一个HttpHelper帮助类

public static class HttpHelper    {        public static T GetApi
(int regattaId, string apiName, string pragm = "") { var client = new RestSharpClient($"{SiteConfig.GetSite("Url")}"); var apiNameStr = string.Format($"{SiteConfig.GetSite($"{apiName}")}", regattaId); var request = client.Execute(string.IsNullOrEmpty(pragm) ? new RestRequest(apiNameStr, Method.GET) : new RestRequest($"{apiNameStr}/{pragm}", Method.GET)); if (request.StatusCode != HttpStatusCode.OK) { return (T)Convert.ChangeType(request.ErrorMessage, typeof(T)); } T result = (T)Convert.ChangeType(request.Content, typeof(T)); return result; }public static T PostApi
(int regattaId, int id, string url, string alias) {
var client = new RestClient($"{url}"); IRestRequest queest = new RestRequest(); queest.Method = Method.POST; queest.AddHeader("Accept", "application/json"); queest.RequestFormat = DataFormat.Json; queest.AddBody(new { userid = id, Url = url, alias = alias, count = 1 }); // uses JsonSerializer var result = client.Execute(queest); if (result.StatusCode != HttpStatusCode.OK) { return (T)Convert.ChangeType(result.ErrorMessage, typeof(T)); } T request = (T)Convert.ChangeType(result.Content, typeof(T)); return request; }}

Setp 5

调用

//Get var notificationlist = HttpHelper.GetApi
(regattaId, "notification");//第二个参数是配置文件中的API地址//PostTask.FromResult(HttpHelper.PostApi
(regattaId, id, url, alias))

在API端接收上述两个请求:

[Route("{regattaId}/[controller]")]        [HttpGet]        public async Task
> GetNotifications(int regattaId) { return await _notificationServices.GetNotifications(regattaId); }[Route("{regattaId}/pageviews")] [HttpPost] // GET: /
/ public async Task PostInfo(int regattaId, [FromBody]PageViewsDto pageViewsDto) { await _pageviewServices.InsertPostInfo(regattaId, pageViewsDto); }

伤处PageViewDto的定义如下:

public class PageViewsDto    {        public int Id { get; set; }        public string Url { get; set; }        public string Alias { get; set; }        public string UserId { get; set; }        public int Count { get; set; }        public PageViewsDto()        {            Id = 0;            Count = 1;        }    }

 

更多详情可访问github:

携带实体参数发送Post请求

假设现在我们需要修改用户的一些基本信息,这些信息需要通过前端 发送到API端,那么该如何实现呢?

public async Task
UpdateUser(PersonModel model) {
var url = $"{SiteConfig.GetSite("Url")}{SiteConfig.GetSite("updateUserByAccount")}"; var resultDetil = await HttpUtil.PostResultAsync
(model, url); return resultDetil; }

前端请求大概如上,地址URL和API名称都再配置文件中获取,下面我们看看PostResultAsync中是如何实现Post请求携带Post参数的吧

///         /// 发起POST请求,并获取请求返回值        ///         /// 
返回值类型
/// 数据实体 /// 接口地址 public static async Task
PostResultAsync
(object obj, string url) { //序列化设置 var setting = new JsonSerializerSettings(); //解决枚举类型序列化时,被转换成数字的问题 setting.Converters.Add(new StringEnumConverter()); setting.NullValueHandling = NullValueHandling.Ignore; var retdata = await HttpPostAsync(url, JsonConvert.SerializeObject(obj, setting)); return JsonConvert.DeserializeObject
(retdata); }

从上面我们可以看出,首先定义了一个泛型方法,其中接收一个参数类型是Object。另一个是url,在这个异步方法体重,我们去call了另一个请求方法

public static async Task
HttpPostAsync(string url, string postData, string certPath = "", string certPwd = "") {
var request = CreateJsonRequest(url, HttpMethod.POST, postData, certPath, certPwd); return await GetResponseStringAsync(request); }
private static HttpWebRequest CreateJsonRequest(string url, HttpMethod method, string postData = "", string certpath = "", string certpwd = "")        {            var request = (HttpWebRequest)WebRequest.Create(url);            request.Method = method.ToString();            request.ContentType = "application/json; charset=utf-8";            request.Accept = "*/*";            request.Timeout = 15000;            request.AllowAutoRedirect = false;            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((a, b, c, d) => true);            if (!string.IsNullOrEmpty(certpath) && !string.IsNullOrEmpty(certpwd))            {                X509Certificate2 cer = new X509Certificate2(certpath, certpwd,                    X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);                request.ClientCertificates.Add(cer);            }            if (method == HttpMethod.POST)            {                using (var sw = new StreamWriter(request.GetRequestStream()))                {                    sw.Write(postData);                }            }            return request;        }private static async Task
GetResponseStringAsync(HttpWebRequest request) { using (var response = await request.GetResponseAsync() as HttpWebResponse) { using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { return reader.ReadToEnd();//获取响应 } } }

上述中的HttpMethod.post为枚举,此枚举中列举了http请求常用格式

public enum HttpMethod    {        GET,        POST    }

让我们看看上面提到的在Api端是如何接收的吧

[Route("[controller]/UpdateUserByAccount")]        [HttpPost]        public async Task
UpdateUserByAccount([FromBody]PersonDto model) { return await _authenticationService.UpdateUserByAccount(model); }

这样,我们就实现了Post请求API时携带实体参数

 

转载于:https://www.cnblogs.com/zhangxiaoyong/p/10771566.html

你可能感兴趣的文章
Java基础学习-流程控制语句
查看>>
Shell中read的常用方式
查看>>
01javascript数据类型
查看>>
asp.net实现md5加密方法详解
查看>>
AJAX
查看>>
table 的thead th 固定 tbody滚动例子
查看>>
并行计算思考----回溯法求解数独问题
查看>>
设计模式:模板模式
查看>>
和菜鸟一起学OK6410之ADC模块
查看>>
代理 模式
查看>>
[git] 细说commit (git add/commit/diff/rm/reset 以及 index 的概念)
查看>>
DOM Core和HTML DOM的区别
查看>>
SurfaceView+MediaPlay的bug们
查看>>
网络表示学习总结
查看>>
完成评论功能
查看>>
far和near
查看>>
Python爬虫实战四之抓取淘宝MM照片
查看>>
2015 Multi-University Training Contest 1
查看>>
C#判断一个字符串是否是数字或者含有某个数字
查看>>
SVN使用指南
查看>>