• .NET Core 技巧汇总篇


    前言

    本篇幅会专门记录在工作中实际碰到的问题场景,和一些比较好的实现方法作为汇总,可以供各位借鉴和参考,当然 本人入行不深,能力有限,仅供各位借鉴和参考。欢迎补充

    技巧一:引入其他项目类库文件

    做项目大家都知道会有远程请求API的情况,现在假设做API的项目你能接触到并且Git下来。那么继续往下看。

    将API项目中用到的Dto引入自己项目。这样方便我们将请求到的json字符串直接序列化成dto,然后再转成我们自己需要的ViewModel,具体怎么转呢,往下看:

    技巧二:使用Extension

    使用Extension,具体怎么用,我们来用一个实际例子说一下吧。比如,我们现在要请求一个所有俱乐部的api。首先我们定义一个ViewModel用于存放俱乐部信息,Model如下:

    ①定义ViewModel

     public class ClubBase
        {
            /// <summary>
            /// 主键Id
            /// </summary>
            public long Id { get; set; }
    
            /// <summary>
            /// 俱乐部名称
            /// </summary>
            public string Name { get; set; }
    
            /// <summary>
            /// 俱乐部描述
            /// </summary>
            public string Description { get; set; }
    
            /// <summary>
            /// 创始人
            /// </summary>
            public string Creator { get; set; }
    
            /// <summary>
            /// 创建年份
            /// </summary>
            public int Year { get; set; }
    
            /// <summary>
            /// 其他信息
            /// </summary>
            public string Contactor { get; set; }
    
            /// <summary>
            /// 手机号
            /// </summary>
            public string Phone { get; set; }
    
            /// <summary>
            /// 地址 例如 中国/深圳
            /// </summary>
            public string Address { get; set; }
    
            /// <summary>
            /// 日期
            /// </summary>
            public DateTime CreationDate { get; set; }
    
        }
    View Code

    ②编写接口

        /// <summary>
        /// 所有接口信息
        /// </summary>
        public interface IDataServices
        {
            /// <summary>
            /// 获取所有俱乐部
            /// </summary>
            /// <returns></returns>
            Task<IList<ClubBase>> GetClubs();
        }

    ③实现Server接口

        /// <summary>
        /// 接口实现类 动态请求api获取相应数据
        /// </summary>
        public class DataServices: IDataServices
        {
            private readonly IDataHttpServers _dataHttpServers;
    
            public DataServices(IDataHttpServers dataHttpServers)
            {
                _dataHttpServers = dataHttpServers;
            }
    
            public async Task<IList<ClubBase>> GetClubs()
            {
    
                var clubsModelList = await _dataHttpServers.GetClubs();
                return clubsModelList;
            }
        }

    ④编写Http请求接口

     public interface IDataHttpServers
        {
            /// <summary>
            /// 获取所有俱乐部
            /// </summary>
            /// <returns></returns>
            Task<IList<ClubBase>> GetClubs();
        }

    ⑤实现此接口

            /// <summary>
            /// 返回俱乐部列表
            /// </summary>
            /// <returns></returns>
            public async Task<IList<ClubBase>> GetClubs()
            {
                return await Task.Run(() => GetClubApi());
            }    
         /// <summary>
            /// 获取所有俱乐部API
            /// </summary>
            /// <returns></returns>
            public List<ClubBase> GetClubApi()
            {
                var list = HttpHelper.GetApi<string>("getclub");
                List<ClubBase> viewClubList = new List<ClubBase>();
                try
                {
                    List<ClubInfoDto> apiClubList = JsonConvert.DeserializeObject<List<ClubInfoDto>>(list);
                    foreach (var item in apiClubList)
                    {
                        //调用拓展方法解耦dto于ViewModel的赋值操作
                        var club = item.TranslateToClubBaseViewModel();
                        viewClubList.Add(club);
                    }
                }
                catch (Exception e)
                {
                    //请求接口api异常,异常描述 list
                }
    
                return viewClubList;
            }

    重头戏也就是此方法了,其中 可以将请求api单独抽离出来写成泛型方法,此处是这样抽离的:

       /// <summary>
        /// HTTPclient 泛型抽象类
        /// </summary>
        public static class HttpHelper
        {
            public static T GetApi<T>(string apiName, string pragm = "")
            {
                var client = new RestSharpClient($"{SiteConfig.GetSite("Url")}");
    
                var request = client.Execute(string.IsNullOrEmpty(pragm)
                    ? new RestRequest($"{SiteConfig.GetSite($"{apiName}")}", Method.GET)
                    : new RestRequest($"{SiteConfig.GetSite($"{apiName}")}/{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;
            }
    
        }

    这里我请求API是使用的RestSharp提供的请求方法。具体可以看这儿  RestSharp  ,需要NuGet安装RestSharp

    这里我稍微贴一下 大概常用的一些接口方法:

    1)接口

     /// <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();
        }
    View Code

    2)实现

     /// <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);
            }
         }
    View Code

    好了,我们接着上面说,大家可以看到,当我们通过请求api获取到数据之后得到的是下面这个Json字符串如下:

    为什么我们需要引入api的dto而不是直接使用ViewModel来赋值我们需要的呢,这里有两个好处,第一个,我们可以快速完成json字符串到对象的转变,第二个,我们可以使用我们下面说的一个小技巧快速过滤出我们想组装的ViewModel即可。

    注意下我们的这个方法TranslateToClubBaseViewModel ,是我们用于操作dto和ViewModel的主要方法

            /// <summary>
            /// 此方法用于将Dto类型 数据 赋值到需要操作的ViewModel上
            /// </summary>
            /// <param name="clubInfoDto">dto数据集</param>
            /// <returns></returns>
            public static ClubBase TranslateToClubBaseViewModel(this ClubInfoDto clubInfoDto)
            {
                ClubBase club = new ClubBase()
                {
                    #region 实体按需赋值
                    Id = clubInfoDto.Id,
                    Address = clubInfoDto.Address,
                    Contactor = clubInfoDto.Contactor,
                    Creator = clubInfoDto.Creator,
                    Description = clubInfoDto.Description,
                    Name = clubInfoDto.Name,
                    Phone = clubInfoDto.Phone,
                    Year = clubInfoDto.Year
                    #endregion
                };
                return club;
            }

    这样操作的好处,我们就不用维护具体的业务层,专注于ViewModel上面。达到了解耦效果。

    RestSharp发送Post请求


    假设我们项目中需要自定义支持所有页面的浏览记录,需要记录再数据库每个页面的详细浏览情况,而不是采用第三方的统计,我们可以这样实现。(假设此处采用的是前后端分离,API的方式读写数据库)

    ①我们在IDataServices接口类中新建一个接口SendBrowseRecord

            /// <summary>
            /// 发送浏览记录
            /// </summary>
            /// <param name="id">用户id,若无则为0</param>
            /// <param name="url">请求页面</param>
            /// <param name="alias">别名</param>
            /// <returns></returns>
            Task<string> SendBrowseRecord(int id, string url, string alias);


    ②在DataServices中实现此接口

    public async Task<string> SendBrowseRecord(int id, string url, string alias)
            {
                return await _dataHttpServers.SendBrowseRecord(id, url, alias);
            }


    ③此处的_dataHttpServers是单独封装起来的访问API的接口,内容和IDataServices一样,但需要注意 在DataServices构造方法中需要注入进来

     private readonly IDataHttpServers _dataHttpServers;
            public DataServices(IDataHttpServers dataHttpServers)
            {
                _dataHttpServers = dataHttpServers;
            }


    ④实现Http的访问SendBrowseRecord方法

     public string SendBrowseRecordApi(int id, string url, string alias)
            {
                try
                {
                    return HttpHelper.PostApi<string>(id, url, alias);
                }
                catch (Exception e)
                {
                    //请求接口api异常,异常描述 list
                    _logger.LogError(e.Message);
                }
    
                return "";
            }
    
    
            public async Task<string> SendBrowseRecord(int id, string url, string alias)
            {
                return await Task.Run(() => SendBrowseRecordApi(id, url, alias));
            }


    因为每个页面都需要去调用这个PostApi,所以此处我将PostApi<T>抽象出一个泛型方法进来,这样不管哪个页面都是调用这个。抽象出来的Post方法如下:
     

    public static T PostApi<T>(int id, string url, string alias)
            {
                var client = new RestClient($"{SiteConfig.GetSite("Url")}api/pageviews");
                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 }); // 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;
            }


    此处的Body是发送一个Json对象。这样,我们就把RestSharp的Post调用实现了。这样就ok啦

           未完待续。。。

  • 相关阅读:
    kafka搭建
    kafaka学习笔记
    metastore 简单说明
    二 python并发编程之多进程-理论
    文件指针偏移量
    FTP
    1 并发编程
    操作系统简介
    1 网络编程
    网络编程-osi七层
  • 原文地址:https://www.cnblogs.com/zhangxiaoyong/p/9419202.html
Copyright © 2020-2023  润新知