打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
.NET Core 下调用WebAPI

1|0前言


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

2|0RestSharp


首先要介绍的就是这款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<Person> response2 = client.Execute<Person>(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<Person>(request, response => {    Console.WriteLine(response.Data.Name);});// abort the request on demandasyncHandle.Abort();

使用案例:

2|1Setp 1


引入RestSharp包

2|2Setp 2


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

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

 

2|3Setp 3


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

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

2|4 Setp 4


新建一个HttpHelper帮助类

public static class HttpHelper    {        public static T GetApi<T>(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<T>(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;        }}

2|5Setp 5


调用

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

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

 [Route("{regattaId}/[controller]")]        [HttpGet]        public async Task<IList<NotificationDto>> GetNotifications(int regattaId)        {            return await _notificationServices.GetNotifications(regattaId);        }[Route("{regattaId}/pageviews")]        [HttpPost]        // GET: /<controller>/        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:https://github.com/restsharp/RestSharp

3|0携带实体参数发送Post请求


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

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

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

         /// <summary>        /// 发起POST请求,并获取请求返回值        /// </summary>        /// <typeparam name="T">返回值类型</typeparam>        /// <param name="obj">数据实体</param>        /// <param name="url">接口地址</param>        public static async Task<T> PostResultAsync<T>(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<T>(retdata);        }

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

public static async Task<string> 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<string> 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<int> UpdateUserByAccount([FromBody]PersonDto model)        {            return await _authenticationService.UpdateUserByAccount(model);        }

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

 


__EOF__

作  者潇十一郎
出  处https://www.cnblogs.com/zhangxiaoyong/p/10771566.html
关于博主:编程路上的小学生,热爱技术,喜欢专研。评论和私信会在第一时间回复。或者直接私信我。
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
SAP调用HTTP和HTTPS
基于DotNetOpenAuth的OAuth实现示例代码: 获取access token
Windows Azure 系列-- 使用Azure + Web API实现图片上传
RestSharp使用说明
wcf系列学习5天速成——第三天 事务的使用
.net 发送qq邮件
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服