.NET Core 技巧汇总篇

简介: 前言 本篇幅会专门记录在工作中实际碰到的问题场景,和一些比较好的实现方法作为汇总,可以供各位借鉴和参考,当然 本人入行不深,能力有限,仅供各位借鉴和参考。欢迎补充   技巧一:引入其他项目类库文件 做项目大家都知道会有远程请求API的情况,现在假设做API的项目你能接触到并且Git下来。

前言

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

 

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

做项目大家都知道会有远程请求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啦

       未完待续。。。

  • 感谢你的阅读。如果你觉得这篇文章对你有帮助或者有启发,就请推荐一下吧~你的精神支持是博主强大的写作动力。欢迎转载!
  • 博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高(其实是个菜B),不足和错误之处在所难免,希望大家能够批评指出。
  • 欢迎加入.NET 从入门到精通技术讨论群→523490820 期待你的加入
  • 不舍得打乱,就永远学不会复原。被人嘲笑的梦想,才更有实现的价值。
  • 我的博客:http://www.cnblogs.com/zhangxiaoyong/
目录
相关文章
|
1月前
|
存储 开发框架 JSON
ASP.NET Core OData 9 正式发布
【10月更文挑战第8天】Microsoft 在 2024 年 8 月 30 日宣布推出 ASP.NET Core OData 9,此版本与 .NET 8 的 OData 库保持一致,改进了数据编码以符合 OData 规范,并放弃了对旧版 .NET Framework 的支持,仅支持 .NET 8 及更高版本。新版本引入了更快的 JSON 编写器 `System.Text.UTF8JsonWriter`,优化了内存使用和序列化速度。
|
2月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
2月前
|
开发框架 .NET 中间件
ASP.NET Core Web 开发浅谈
本文介绍ASP.NET Core,一个轻量级、开源的跨平台框架,专为构建高性能Web应用设计。通过简单步骤,你将学会创建首个Web应用。文章还深入探讨了路由配置、依赖注入及安全性配置等常见问题,并提供了实用示例代码以助于理解与避免错误,帮助开发者更好地掌握ASP.NET Core的核心概念。
100 3
|
1月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
2月前
|
开发框架 NoSQL .NET
利用分布式锁在ASP.NET Core中实现防抖
【9月更文挑战第5天】在 ASP.NET Core 中,可通过分布式锁实现防抖功能,仅处理连续相同请求中的首个请求,其余请求返回 204 No Content,直至锁释放。具体步骤包括:安装分布式锁库如 `StackExchange.Redis`;创建分布式锁服务接口及其实现;构建防抖中间件;并在 `Startup.cs` 中注册相关服务和中间件。这一机制有效避免了短时间内重复操作的问题。
|
3月前
|
开发框架 监控 .NET
开发者的革新利器:ASP.NET Core实战指南,构建未来Web应用的高效之道
【8月更文挑战第28天】本文探讨了如何利用ASP.NET Core构建高效、可扩展的Web应用。ASP.NET Core是一个开源、跨平台的框架,具有依赖注入、配置管理等特性。文章详细介绍了项目结构规划、依赖注入配置、中间件使用及性能优化方法,并讨论了安全性、可扩展性以及容器化的重要性。通过这些技术要点,开发者能够快速构建出符合现代Web应用需求的应用程序。
58 0
|
3月前
|
缓存 数据库连接 API
Entity Framework Core——.NET 领域的 ORM 利器,深度剖析其最佳实践之路
【8月更文挑战第28天】在软件开发领域,高效的数据访问与管理至关重要。Entity Framework Core(EF Core)作为一款强大的对象关系映射(ORM)工具,在 .NET 开发中扮演着重要角色。本文通过在线书店应用案例,展示了 EF Core 的核心特性和优势。我们定义了 `Book` 实体类及其属性,并通过 `BookStoreContext` 数据库上下文配置了数据库连接。EF Core 提供了简洁的 API,支持数据的查询、插入、更新和删除操作。
116 0
|
3月前
|
开发框架 监控 .NET
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
|
3月前
|
Linux C# C++
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
|
3月前
|
开发框架 .NET API
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
189 0