前言

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

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

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

②编写接口

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

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);
}
}

好了,我们接着上面说,大家可以看到,当我们通过请求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啦

未完待续。。。

.NET Core 技巧汇总篇的更多相关文章

  1. 25个增强iOS应用程序性能的提示和技巧(中级篇)(3)

    25个增强iOS应用程序性能的提示和技巧(中级篇)(3) 2013-04-16 14:42 破船之家 beyondvincent 字号:T | T 本文收集了25个关于可以提升程序性能的提示和技巧,分 ...

  2. 25个增强iOS应用程序性能的提示和技巧--中级篇

    25个增强iOS应用程序性能的提示和技巧--中级篇 标签: ios性能优化内存管理 2013-12-13 10:55 738人阅读 评论(0) 收藏 举报  分类: IPhone开发高级系列(34)  ...

  3. 移动平台3G手机网站前端开发布局技巧汇总

    移动平台3G手机网站前端开发布局技巧汇总 作者:前端开发-武方博   发布:2011-05-10 09:11   分类:移动开发   阅读:120,618 views   7条评论     您或许正在 ...

  4. 移动平台WEB前端开发技巧汇总(转)

    最近我很关注移动前端的知识,但做为一个UI设计师和web前端工作人员没有这个工作环境接触,做为门外汉,网上系统的知识也了了,一直有种雾里看花的感觉,见到本文,我自己是奉为经典.所以我分享之后又专门打笔 ...

  5. 25个增强iOS应用程序性能的提示和技巧 — 中级篇

    本文由破船译自:raywenderlich 转载请注明出处:BeyondVincent的博客 _____________ 在开发iOS应用程序时.让程序具有良好的性能是非常关键的.这也是用户所期望的. ...

  6. Oracle 数据库知识汇总篇

    Oracle 数据库知识汇总篇(更新中..) 1.安装部署篇 2.管理维护篇 3.数据迁移篇 4.故障处理篇 5.性能调优篇 6.SQL PL/SQL篇 7.考试认证篇 8.原理体系篇 9.架构设计篇 ...

  7. Vertica 数据库知识汇总篇

    Vertica 数据库知识汇总篇(更新中..) 1.Vertica 集群软件部署,各节点硬件性能测试 2.Vertica 创建数据库,创建业务用户测试 3.Vertica 数据库参数调整,资源池分配 ...

  8. 25个增强iOS应用程序性能的提示和技巧(高级篇)(2)

    25个增强iOS应用程序性能的提示和技巧(高级篇)(2) 2013-04-16 14:56 破船之家 beyondvincent 字号:T | T 在开发iOS应用程序时,让程序具有良好的性能是非常关 ...

  9. 25个增强iOS应用程序性能的提示和技巧(高级篇)(1)

    25个增强iOS应用程序性能的提示和技巧(高级篇)(1) 2013-04-16 14:56 破船之家 beyondvincent 字号:T | T 在开发iOS应用程序时,让程序具有良好的性能是非常关 ...

随机推荐

  1. User Profile Service服务未能登录,无法登录

    不知你是否遇到这样的问题,某一天你打开PC,开机正常,可当你输入正确的密码回车,却发现Vista或Win7拒绝让你登录,提示"User Profile Service 服务未能登录.无法加载 ...

  2. 在Windows Server 2008 R2下搭建jsp环境(二)-JDK的下载安装

    因为服务器上的Tomcat的运行环境需要JDK的支持,所以,掌握JDK的安装与下载和配置是一个重要步骤.   1.首先下载最新的JDK版本.网络上提供了最新版本的JDK下载,如图所示.首先选择&quo ...

  3. BZOJ_5301_[Cqoi2018]异或序列&&CF617E_莫队

    Description 已知一个长度为 n 的整数数列 a[1],a[2],…,a[n] ,给定查询参数 l.r ,问在 [l,r] 区间内,有多少连续子 序列满足异或和等于 k . 也就是说,对于所 ...

  4. MySQL-5.6.36-多实例-部署(编译版)

    MySQL多实例_沁贰百科 注:部署双实例前,首先需要部署单实例,单实例部署详情如下: https://www.cnblogs.com/wangqiner/p/9081002.html 1.如已经安装 ...

  5. appium----【已解决】【Mac】ANDROID_HOME的环境变量配置

    在搭建appium的环境时,提示Android_home的环境没有配置,经过一会的奋战终于解决,再次记录下解决方式. 1.安装android-sdk-macosx 下载路径:http://down.t ...

  6. Android之微信朋友圈UI实现--ExpandableListView+GridView

    PS:我们都知道微信,更是知道朋友圈,很多人在朋友圈里卖起了化妆品,打入广告等为自己做一下推广,里面会附带一写好看的图片,上面有标题,有描述,整体布局每场的美观,那么这是怎么实现的呢,有些人可能会单个 ...

  7. FTRL(Follow The Regularized Leader)学习总结

    摘要: 1.算法概述 2.算法要点与推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 FTRL是一种适用于处理超大规模数据的,含大量稀疏特征的在线学习的 ...

  8. JS 图片放大镜

    今天练习一个小demo, 从本地读取图片, 然后实现类似淘宝放大镜的效果, 再加两个需求 1 .可以调节缩放比例,默认放大两倍 2 . 图片宽高自适应, 不固定宽高 话不多说先看效果: 原理:1, 右 ...

  9. php SESSION入库的实现

    session入库,就是重写session制机,在session的周期内,获得到session的数据并记录到数据库 Session默认是存放到服务器上的文件中,不方便管理,如果能把session存放到 ...

  10. Node中流的概念

    在学习node的过程中,对于流的概念一直不是很理解,通过查阅一些资料,现在将自己对流的一些理解进行总结一下. 一.流的理解 首先我们必须知道什么是流,很多书中只是提到使用流读写文件怎么怎么方便,却不提 ...