在上個月寫過一篇 .NET 純原生實現 Cron 定時任務執行,未依賴第三方組件 的文章,當時 CronSchedule 的實現是使用了,每個服務都獨立進入到一個 while 迴圈中,進行定期掃描是否到了執行時間來實現的,但是那個邏輯有些問題,經過各位朋友的測試,發現當多個任務的時候存在一定概率不按 ...
前沿
近年來,隨著互聯網的發展,各個行業都在用新的技術、新的觀念為自己的發展打下堅實的基礎,如今網路已經滲透到了人們的日常生活中,網上購物成了大家喜愛的方式。各類商城、APP、小程式等應用不斷涌現,涉及各行各業,都在爭搶成為人們網上購物的載體。網上購物物流是必不可少的一環,這些應用是如何解決物流信息系統化的,讓消費者方便快捷的瞭解物品的實時軌跡信息和系統內部流程無阻礙自動流轉?我認為有兩種途徑可達成,第一種是自建物流體系,逐個跟物流公司對接,設計符合自身的產品解決問題,這種方案的優點是靈活性非常高,高度契合公司系統,缺點也很明顯,每家公司介面標準都不一樣,需要懂物流的人抽象設計,接入難度大、耗時長、成本高、後期的維護成本也高。第二種是找一家第三方聚合物流平臺接入即可,如:快遞鳥、快遞100、快遞網等。物流平臺對物流和電商兩端的需求研究更深入,產品設計得更簡單,對接更快捷,更重要的一點是只需一次接入即可使用平臺支持的所有快遞物流公司,開發周期短,後期維護成本低,缺點是這些平臺都是標準介面,靈活性稍低,介面調用量大時需支付介面調用服務費,各家平臺的收費標準都不一樣,可登錄其官網瞭解詳情,下麵為大家介紹如何接入快遞鳥快遞物流查詢API。
應用場景
綜合類電商平臺、垂直類電商平臺、小程式、ERP系統、工具等應用都可使用。
如電商平臺在訂單管理頁面可查看物流軌跡信息
小程式通過掃碼查看快遞行蹤
接入步驟
申請賬號-->獲取用戶ID和Key-->申請開通套餐-->按要求對接,聯調測試-->正式投產
1、申請賬號和開通套餐
訪問快遞鳥註冊頁面進行賬號註冊,按頁面提示,完成賬號註冊和完善資料,賬號註冊成功後可在用戶中心查看獲得用戶ID和Key,同時在用戶中心頂部點擊申請開通套餐,這樣子對接前期準備工作就完成了,使用ID和Key即可進行調用。
2、技術對接
訪問快遞鳥文檔中心下載技術對接文檔,快遞鳥產品很多,選擇適合自己的產品,根據文檔參數對接即可。需要註意的是,對接過程如果遇到簽名校驗不過的問題,這時可查看生成驗簽的方式是否與文檔一致,生成的驗簽是否存在大小寫的問題,快遞鳥的驗簽生成方式為:(請求內容(未編碼)+ApiKey)進行MD5加密,然後Base64編碼,最後進行URL(utf-8)編碼。好了,不啰嗦了,直接上代碼,如需對接的產品與示例不同只需更改requestType和應用級參數即可。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace KuaiDiChaXun
{
/// <summary>
/// 快遞查詢處理類
/// </summary>
public class KuaiDiChaXunBLL
{
#region 固定參數,實際項目中可寫在配置文件中,方便修改
string url = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";//請求url,正式環境
string eBusinessID = "1257157";//用戶ID,此ID僅作演示使用,實際調用需換成自己的ID,登錄快遞鳥官網會員中心獲取
string apiKey = "F201358A-513B-4237-98D6-67DE7EA75BA3";//用戶秘鑰,此秘鑰僅作演示使用,實際調用需換成自己的秘鑰,登錄快遞鳥官網會員中心獲取
#endregion
/// <summary>
/// 查詢快遞路由軌跡
/// </summary>
/// <param name="shipperCode">快遞公司編碼</param>
/// <param name="waybillCode">運單號</param>
/// <param name="phoneNo">收/寄件人手機號後4位,SF必填</param>
/// <returns></returns>
public string SearchRoute(string shipperCode, string waybillCode, string phoneNo)
{
if (string.IsNullOrEmpty(shipperCode))
{
return "請輸入快遞公司編碼";
}
if (string.IsNullOrEmpty(waybillCode))
{
return "請輸入運單號";
}
if (string.IsNullOrEmpty(phoneNo) && shipperCode == "SF")
{
return "SF必填收/寄件人手機號後4位";
}
string result = string.Empty;
//組裝應用級參數,此Demo使用最少參數,更多參數參考技術文檔
string requestData = "{'ShipperCode':'" + shipperCode + "','LogisticCode':'" + waybillCode + "'}";
if (shipperCode == "SF")//順豐需收/寄件人手機號後4位
{
requestData = "{'ShipperCode':'" + shipperCode + "','LogisticCode':'" + waybillCode + "','CustomerName':'" + phoneNo + "'}";
}
//把(jsonStr+APIKey)進行MD5加密
string md5Str = MD5(requestData + apiKey, "UTF-8");
//把md5Str 進行Base64編碼
string base64Str = base64(md5Str, "UTF-8");
//進行URL編碼 (utf-8),最終得到簽名串
string dataSign = HttpUtility.UrlEncode(base64Str, Encoding.UTF8);
//請求介面指令
string cmd = "8001";
//組裝系統級參數
string postData = "RequestData=" + HttpUtility.UrlEncode(requestData, Encoding.UTF8) + "&EBusinessID=" + eBusinessID + "&RequestType="+ cmd + "&DataSign=" + dataSign + "&DataType=2";
//發起請求
HttpHelper helper = new HttpHelper();
HttpRequestEntity response = helper.Request(url, postData);
if (response.IsSuccess == 0)
{
result = response.ResponseContent;
//拿到結果後進行後續業務操作
}
else
{
result = "請求異常";
//記錄錯誤信息及後續業務補償
}
return result;
}
///<summary>
/// 字元串MD5加密
///</summary>
///<param name="str">要加密的字元串</param>
///<param name="charset">編碼方式</param>
///<returns>密文</returns>
public string MD5(string str, string charset)
{
byte[] buffer = Encoding.GetEncoding(charset).GetBytes(str);
try
{
System.Security.Cryptography.MD5CryptoServiceProvider check;
check = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] somme = check.ComputeHash(buffer);
string ret = "";
foreach (byte a in somme)
{
if (a < 16)
ret += "0" + a.ToString("X");
else
ret += a.ToString("X");
}
return ret.ToLower();
}
catch
{
throw;
}
}
/// <summary>
/// base64編碼
/// </summary>
/// <param name="str">內容</param>
/// <param name="charset">編碼方式</param>
/// <returns></returns>
public string base64(string str, string charset)
{
return Convert.ToBase64String(Encoding.GetEncoding(charset).GetBytes(str));
}
}
}
HTTP封裝類代碼:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace KuaiDiChaXun
{
public class HttpHelper : IDisposable
{
private bool _disposable = false;
/// <summary>
/// 請求編碼格式預設utf-8;
/// </summary>
public Encoding HtmlEncoding = Encoding.UTF8;
/// <summary>
/// 請求時間
/// </summary>
public int Timeout = 5000;
public CookieContainer Cookies = null;
/// <summary>
/// 是否記錄Cookies
/// </summary>
public bool IsRecordCookie = false;
public string ContentType = "application/x-www-form-urlencoded";
public string AcceptLanguage = "en-US, en; q=0.8, zh-Hans-CN; q=0.5, zh-Hans; q=0.3";
public string KeepAlive = "Keep-Alive";
public string Accept = "*/*";
private const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240";
public HttpHelper()
{
//允許最大連接數
ServicePointManager.DefaultConnectionLimit = 512;
}
/// <summary>
/// 基本請求方法
/// </summary>
/// <param name="requestType"></param>
/// <param name="url"></param>
/// <param name="requestData"></param>
/// <returns></returns>
private HttpRequestEntity BaseRequest(RequestType requestType, string url, string requestData)
{
var result = new HttpRequestEntity { IsSuccess = 0 };
if (string.IsNullOrEmpty(url))
throw new ArgumentNullException("請求Url不能為空值");
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
HttpStatusCode statusCode = HttpStatusCode.OK;
if (IsRecordCookie)
Cookies = new CookieContainer();
Stream requestStream = null;
StreamReader streamReader = null;
HttpWebRequest webRe = null;
HttpWebResponse webPos = null;
try
{
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
webRe = WebRequest.Create(url) as HttpWebRequest;
webRe.ProtocolVersion = HttpVersion.Version10;
}
else
{
webRe = (HttpWebRequest)WebRequest.Create(url);
}
webRe.Headers.Add("Accept-Language", AcceptLanguage);
webRe.Headers.Add("Keep-Alive", KeepAlive);
webRe.UserAgent = UserAgent;
webRe.Accept = Accept;
webRe.Timeout = Timeout;
webRe.ReadWriteTimeout = Timeout;
webRe.CookieContainer = Cookies;
if (requestType == RequestType.Post)
{
webRe.ContentType = string.Format("{0}; {1}", ContentType, HtmlEncoding.BodyName);
byte[] datas = HtmlEncoding.GetBytes(requestData);
webRe.Method = "POST";
webRe.ContentLength = datas.Length;
webRe.MaximumResponseHeadersLength = -1;
requestStream = webRe.GetRequestStream();
requestStream.Write(datas, 0, datas.Length);
requestStream.Flush();
requestStream.Close();
}
else
webRe.Method = "GET";
webPos = (HttpWebResponse)webRe.GetResponse();
statusCode = webPos.StatusCode;
result.ResponseLength = webPos.ContentLength;
result.ResponseEncodingName = webPos.ContentEncoding;
requestStream = webPos.GetResponseStream();
if (webPos.StatusCode == HttpStatusCode.OK)
{
result.IsSuccess = 0;
if (requestStream != null)
{
streamReader = new StreamReader(requestStream, HtmlEncoding);
result.ResponseContent = streamReader.ReadToEnd();
}
}
}
catch (Exception ex)
{
result.IsSuccess = 1;
result.ResponseContent = ex.Message;
}
finally
{
if (requestStream != null)
{
requestStream.Close();
requestStream.Dispose();
}
if (streamReader != null)
{
streamReader.Close();
streamReader.Dispose();
}
webRe.Abort();
if (webPos != null)
webPos.Close();
}
stopwatch.Stop();
double elapseTime = stopwatch.Elapsed.TotalMilliseconds;//計算請求耗時
return result;
}
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true; //總是接受
}
/// <summary>
/// Get請求
/// </summary>
/// <param name="url">請求地址</param>
/// <returns></returns>
public HttpRequestEntity Request(string url)
{
return BaseRequest(RequestType.Get, url, string.Empty);
}
/// <summary>
/// Post請求
/// </summary>
/// <param name="url">請求地址Url</param>
/// <param name="requestData">請求內容參數</param>
/// <returns></returns>
public HttpRequestEntity Request(string url, string requestData)
{
return BaseRequest(RequestType.Post, url, requestData);
}
~HttpHelper()
{
Dispose(false);
}
#region IDisposable 成員
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (this._disposable)
return;
if (disposing)
{
}
_disposable = true;
}
#endregion
}
/// <summary>
/// HttpHelper請求方式
/// </summary>
public enum RequestType
{
/// <summary>
/// Get請求
/// </summary>
Get,
/// <summary>
/// Post請求
/// </summary>
Post
}
/// <summary>
/// HttpHelper請求時返回實體
/// </summary>
public class HttpRequestEntity
{
/// <summary>
/// 請求是否成功 0-成功(返回Http狀態碼200) 1-失敗(出現異常)
/// </summary>
public int IsSuccess { get; set; }
/// <summary>
/// 請求返回內容
/// </summary>
public string ResponseContent { get; set; }
/// <summary>
/// 請求返回內容長度
/// </summary>
public long ResponseLength { get; set; }
/// <summary>
/// 請求返回編碼類型
/// </summary>
public string ResponseEncodingName { get; set; }
}
}
調用示例代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KuaiDiChaXun
{
class Program
{
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("請輸入快遞公司編碼");
string shipperCode = Console.ReadLine();
Console.WriteLine("請輸入運單號");
string waybillCode = Console.ReadLine();
Console.WriteLine("請輸入收/寄件人手機號後4位,SF必填");
string phone = Console.ReadLine();
KuaiDiChaXunBLL bll = new KuaiDiChaXunBLL();
string result = bll.SearchRoute(shipperCode, waybillCode, phone);
Console.WriteLine("執行結果如下:");
Console.WriteLine(result);
Console.WriteLine("------------------");
Console.WriteLine("------本次查詢結束,按任意鍵繼續,退出請輸入exit------------");
string cmd = Console.ReadLine().ToLower();
if (cmd == "exit")
{
return;
}
}
}
}
}
運行查看效果
以上是接入快遞鳥快遞查詢介面示例代碼,源碼下載
如果對您有幫助勞煩幫忙點個贊,收藏關註一下,可以相互學習共同進步。
本文來自博客園,作者:華小睿,轉載請註明原文鏈接:https://www.cnblogs.com/huaxiaorui/p/16662542.html