using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Net;
|
using System.Security.Cryptography;
|
using System.Text;
|
using HDL_ON.Entity;
|
using RestSharp;
|
|
namespace HDL_ON.DAL.Server
|
{
|
public class HttpUtil
|
{
|
|
#region **********全局常量**********
|
/// <summary>
|
/// 固定域名,正式环境
|
/// 公共域名就近解析
|
/// </summary>
|
//public const string GlobalRequestHttpsHost = "https://nearest.hdlcontrol.com";
|
public const string GlobalRequestHttpsHost = "https://test-gz.hdlcontrol.com";//mmmm
|
/// <summary>
|
/// RegionMark
|
/// </summary>
|
public const string RegionMark = "HDL";
|
/// <summary>
|
/// 请求超时时间
|
/// </summary>
|
public const int TIME_OUT = 15;
|
/// <summary>
|
/// 特殊接口请求超时时间
|
/// </summary>
|
public const int TIME_OUT_LONG = 20;
|
/////// <summary>
|
/////// Bearer 暂时设为空,从登陆成功的返回的headerPrefix参数动态获取
|
/////// </summary>
|
//public const string TOKEN_BEARER = "Bearer ";
|
|
#endregion
|
|
#region **********网络请求封装**********
|
|
/// <summary>
|
/// Get 请求服务器方法
|
/// </summary>
|
/// <param name="apiPath"></param>
|
/// <param name="queryDictionary"></param>
|
/// <param name="urlSegmentDictionary"></param>
|
/// <param name="urlHead"></param>
|
/// <param name="replaceToken"></param>
|
/// <param name="mTimeout"></param>
|
/// <returns></returns>
|
public static ResponsePackNew RequestHttpsGet(string apiPath, Dictionary<string, object> queryDictionary = null, Dictionary<string, object> urlSegmentDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
|
{
|
return RequestHttps(Method.GET, apiPath, null, queryDictionary, urlSegmentDictionary, urlHead, replaceToken, mTimeout);
|
}
|
|
///// <summary>
|
///// 通用 请求服务器方法
|
///// </summary>
|
///// <param name="method">请求类型</param>
|
///// <param name="apiPath"></param>
|
///// <param name="bodyParameterJson"></param>
|
///// <param name="queryDictionary"></param>
|
///// <param name="urlSegmentDictionary"></param>
|
///// <param name="urlHead"></param>
|
///// <param name="mTimeout">请求超时时间,默认10</param>
|
///// <param name="urlHead"></param>
|
///// <returns></returns>
|
//public static ResponsePackNew RequestHttpsBase(Method method, string apiPath, string bodyParameterJson = null, Dictionary<string, object> queryDictionary = null, Dictionary<string, object> urlSegmentDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT, bool needErrorTip = true)
|
//{
|
// var mResponsePackNew = RequestHttps(method, apiPath, bodyParameterJson, queryDictionary, urlSegmentDictionary, urlHead, replaceToken, mTimeout);
|
// if (needErrorTip)
|
// {
|
// if (mResponsePackNew.Code.ToUpper() != SUCCESS_CODE)
|
// {
|
// IMessageCommon.Current.ShowErrorInfoAlter(apiPath, mResponsePackNew.Code);
|
// }
|
// }
|
// return mResponsePackNew;
|
//}
|
|
/// <summary>
|
/// POST请求方法 body参数
|
/// 针对住宅相关接口封装
|
/// 调用住宅当前所在区域域名
|
/// 如果是分享住宅,使用主人的token进行相关操作
|
/// </summary>
|
/// <param name="apiPath"></param>
|
/// <param name="bodyParameterJson"></param>
|
/// <param name="mTimeout"></param>
|
/// <returns></returns>
|
public static ResponsePackNew RequestHttpsPostFroHome(string apiPath, string bodyParameterJson, int mTimeout = TIME_OUT)
|
{
|
string urlHead = DB_ResidenceData.Instance.CurrentRegion.regionUrl;
|
//var replaceToken = "";
|
//if (DB_ResidenceData.residenceData.residecenInfo.IsOthreShare)
|
//{
|
// replaceToken = DB_ResidenceData.residenceData.MasterToken;
|
//}
|
return RequestHttps(Method.POST, apiPath, bodyParameterJson, null, null, urlHead, "", mTimeout);
|
}
|
|
/// <summary>
|
/// POST请求方法 body参数
|
/// </summary>
|
/// <param name="apiPath"></param>
|
/// <param name="bodyParameterJson"></param>
|
/// <param name="urlHead"></param>
|
/// <param name="needErrorTip"></param>
|
/// <param name="replaceToken"></param>
|
/// <param name="mTimeout"></param>
|
/// <returns></returns>
|
public static ResponsePackNew RequestHttpsPost(string apiPath, string bodyParameterJson, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
|
{
|
return RequestHttps(Method.POST, apiPath, bodyParameterJson, null, null, urlHead, replaceToken, mTimeout);
|
}
|
|
/// <summary>
|
/// POST请求方法 queryDictionary
|
/// </summary>
|
/// <param name="apiPath"></param>
|
/// <param name="queryDictionary"></param>
|
/// <param name="urlHead"></param>
|
/// <param name="needErrorTip"></param>
|
/// <param name="replaceToken"></param>
|
/// <param name="mTimeout"></param>
|
/// <returns></returns>
|
public static ResponsePackNew RequestHttpsPost(string apiPath, Dictionary<string, object> queryDictionary, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
|
{
|
return RequestHttps(Method.POST, apiPath, null, queryDictionary, null, urlHead, replaceToken, mTimeout);
|
}
|
|
/// <summary>
|
/// 通用 请求服务器方法
|
/// </summary>
|
/// <param name="method"></param>
|
/// <param name="apiPath"></param>
|
/// <param name="bodyParameterJson"></param>
|
/// <param name="queryDictionary"></param>
|
/// <param name="urlSegmentDictionary"></param>
|
/// <param name="urlHead"></param>
|
/// <param name="replaceToken"></param>
|
/// <param name="mTimeout"></param>
|
/// <returns></returns>
|
static ResponsePackNew RequestHttpsBase(Method method, string apiPath, string bodyParameterJson = null, Dictionary<string, object> queryDictionary = null, Dictionary<string, object> urlSegmentDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
|
{
|
//Dome模式登录
|
|
if(MainPage.NoLoginMode)
|
{
|
return new ResponsePackNew() { Code = "0" };
|
}
|
#region HttpWebRequest
|
try
|
{
|
|
if (string.IsNullOrEmpty(urlHead))
|
{
|
urlHead = OnAppConfig.Instance.RequestHttpsHost;
|
}
|
string requestFullUrl = urlHead + apiPath;
|
|
|
RestClient client = new RestClient(requestFullUrl);
|
|
RestRequest request = new RestRequest(method);
|
request.Timeout = mTimeout * 1000;
|
request.AddHeader("content-type", "application/json");
|
|
if (string.IsNullOrEmpty(replaceToken))
|
{
|
if(UserInfo.Current != null)
|
{/* 如果不需要验证Token可以不用传入 */
|
request.AddHeader("Authorization", UserInfo.Current.LoginTokenString);
|
}
|
}
|
else
|
{
|
request.AddHeader("Authorization", replaceToken);
|
}
|
|
if (bodyParameterJson != null)
|
{
|
request.AddParameter("application/json", bodyParameterJson, ParameterType.RequestBody);
|
}
|
|
if (queryDictionary != null)
|
{
|
foreach (var data in queryDictionary)
|
{
|
request.AddQueryParameter(data.Key, data.Value.ToString());
|
}
|
}
|
|
if (urlSegmentDictionary != null)
|
{
|
foreach (var data in urlSegmentDictionary)
|
{
|
request.AddUrlSegment(data.Key, data.Value.ToString());
|
}
|
}
|
|
IRestResponse response = client.Execute(request);
|
if (response.StatusCode == HttpStatusCode.OK)
|
{
|
try
|
{
|
ResponsePackNew revertObj = new ResponsePackNew() { };
|
revertObj = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePackNew>(response.Content);
|
//*****一些判空处理*****************
|
if (revertObj.Code == null)
|
{
|
revertObj.Code = StateCode.DATA_EXCEPTION;
|
}
|
|
if (revertObj.Data == null)
|
{
|
revertObj.Data = "";
|
}
|
//*****一些判空处理*****************
|
|
return revertObj;
|
}
|
catch (Exception ex)
|
{
|
HDL_ON.Utlis.WriteLine(ex.Message);
|
return new ResponsePackNew() { Code = StateCode.DATA_EXCEPTION };
|
}
|
}
|
else
|
{
|
HDL_ON.Utlis.WriteLine(response.Content);
|
return new ResponsePackNew() { Code = StateCode.NETWORK_ERROR };
|
}
|
|
}
|
catch (Exception ex)
|
{
|
HDL_ON.Utlis.WriteLine(ex.Message);
|
return new ResponsePackNew() { Code = StateCode.NETWORK_ERROR };
|
}
|
|
#endregion
|
|
}
|
|
/// <summary>
|
/// 通用 请求服务器方法
|
/// 增加token过期处理
|
/// </summary>
|
/// <param name="method"></param>
|
/// <param name="apiPath"></param>
|
/// <param name="bodyParameterJson"></param>
|
/// <param name="queryDictionary"></param>
|
/// <param name="urlSegmentDictionary"></param>
|
/// <param name="urlHead"></param>
|
/// <param name="replaceToken"></param>
|
/// <param name="mTimeout"></param>
|
/// <returns></returns>
|
public static ResponsePackNew RequestHttps(Method method, string apiPath, string bodyParameterJson = null, Dictionary<string, object> queryDictionary = null, Dictionary<string, object> urlSegmentDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
|
{
|
var responsePackNew = RequestHttpsBase(method, apiPath, bodyParameterJson, queryDictionary, urlSegmentDictionary, urlHead, replaceToken, mTimeout);
|
//*****************Token过期处理*****************
|
if (responsePackNew.Code == StateCode.TOKEN_EXPIRED)
|
{
|
//刷新Token
|
if (RefreshToken()) {
|
return RequestHttpsBase(method, apiPath, bodyParameterJson, queryDictionary, urlSegmentDictionary, urlHead, replaceToken, mTimeout);
|
}
|
else
|
{
|
return responsePackNew;
|
}
|
}
|
//*****************Token过期处理*****************
|
return responsePackNew;
|
}
|
|
|
/// <summary>
|
/// 刷新 Token
|
/// </summary>
|
/// <returns></returns>
|
static bool RefreshToken()
|
{
|
try
|
{
|
var requestJson = GetSignRequestJson(new RefreshTokenObj()
|
{
|
refreshToken = UserInfo.Current.RefreshToken,
|
});
|
var revertObj = RequestHttpsBase(Method.POST, NewAPI.API_POST_Login, requestJson);
|
if (revertObj.Code == StateCode.SUCCESS)
|
{
|
var revertData = Newtonsoft.Json.JsonConvert.DeserializeObject<UserLoginRes>(revertObj.Data.ToString());
|
UserInfo.Current.LoginTokenString = revertData.headerPrefix + revertData.accessToken;
|
UserInfo.Current.RefreshToken = revertData.refreshToken;
|
UserInfo.Current.LastTime = DateTime.Now;
|
UserInfo.Current.SaveUserInfo();
|
return true;
|
}
|
return false;
|
}
|
catch
|
{
|
return false;
|
}
|
}
|
|
/// <summary>
|
/// 下载文件 请求服务器方法
|
/// </summary>
|
/// <param name="apiPath"></param>
|
/// <param name="bodyParameterJson"></param>
|
/// <param name="queryDictionary"></param>
|
/// <param name="urlHead"></param>
|
/// <param name="replaceToken"></param>
|
/// <param name="mTimeout"></param>
|
/// <returns></returns>
|
public static byte[] RequestHttpsDownload(string apiPath, string bodyParameterJson = null, Dictionary<string, object> queryDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = 20)
|
{
|
#region RestRequest
|
try
|
{
|
if (string.IsNullOrEmpty(urlHead))
|
{
|
urlHead = OnAppConfig.Instance.RequestHttpsHost;
|
}
|
string requestFullUrl = urlHead + apiPath;
|
|
RestClient client = new RestClient(requestFullUrl);
|
RestRequest request = new RestRequest(Method.POST);
|
request.Timeout = mTimeout * 1000;
|
request.AddHeader("content-type", "application/json");
|
|
if (string.IsNullOrEmpty(replaceToken))
|
{
|
if ( UserInfo.Current != null)
|
{/* 如果不需要验证Token可以不用传入 */
|
request.AddHeader("Authorization", UserInfo.Current.LoginTokenString);
|
}
|
}
|
else
|
{
|
request.AddHeader("Authorization", replaceToken);
|
}
|
|
if (bodyParameterJson != null)
|
{
|
request.AddParameter("application/json", bodyParameterJson, ParameterType.RequestBody);
|
}
|
|
if (queryDictionary != null)
|
{
|
foreach (var data in queryDictionary)
|
{
|
request.AddQueryParameter(data.Key, data.Value.ToString());
|
}
|
}
|
|
IRestResponse response = client.Execute(request);
|
return response.RawBytes;
|
}
|
catch (Exception ex)
|
{
|
HDL_ON.Utlis.WriteLine(ex.Message);
|
return null;
|
}
|
#endregion
|
|
}
|
|
/// <summary>
|
/// 上传 请求服务器方法
|
/// </summary>
|
/// <param name="method"></param>
|
/// <param name="apiPath"></param>
|
/// <param name="bodyParameterObject"></param>
|
/// <param name="queryDictionary"></param>
|
/// <param name="urlSegmentDictionary"></param>
|
/// <param name="urlHead"></param>
|
/// <param name="replaceToken"></param>
|
/// <param name="mTimeout"></param>
|
/// <returns></returns>
|
public static ResponsePackNew RequestHttpsUpload(Method method, string apiPath, object bodyParameterObject = null, Dictionary<string, object> queryDictionary = null, Dictionary<string, object> urlSegmentDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
|
{
|
#region HttpWebRequest
|
try
|
{
|
|
if (string.IsNullOrEmpty(urlHead))
|
{
|
urlHead = OnAppConfig.Instance.RequestHttpsHost;
|
}
|
string requestFullUrl = urlHead + apiPath;
|
|
////**************测试**************
|
//string requestFullUrl = GlobalRequestHttpsHost + apiPath;
|
////**************测试**************
|
|
RestClient client = new RestClient(requestFullUrl);
|
//client.Timeout = mTimeout * 1000;
|
RestRequest request = new RestRequest(method);
|
request.Timeout = mTimeout * 1000;
|
//request.AddHeader ("content-type", "application/json");
|
request.AddHeader("content-type", "application/octet-stream");
|
|
if (string.IsNullOrEmpty(replaceToken))
|
{
|
if ( UserInfo.Current != null)
|
{/* 如果不需要验证Token可以不用传入 */
|
request.AddHeader("Authorization", UserInfo.Current.LoginTokenString);
|
}
|
}
|
else
|
{
|
request.AddHeader("Authorization", replaceToken);
|
}
|
|
if (bodyParameterObject != null)
|
{
|
request.AddParameter("application/octet-stream", bodyParameterObject, ParameterType.RequestBody);
|
}
|
|
if (queryDictionary != null)
|
{
|
foreach (var data in queryDictionary)
|
{
|
request.AddQueryParameter(data.Key, data.Value.ToString());
|
}
|
}
|
|
if (urlSegmentDictionary != null)
|
{
|
foreach (var data in urlSegmentDictionary)
|
{
|
request.AddUrlSegment(data.Key, data.Value.ToString());
|
}
|
}
|
|
IRestResponse response = client.Execute(request);
|
if (response.StatusCode == HttpStatusCode.OK)
|
{
|
try
|
{
|
ResponsePackNew revertObj = new ResponsePackNew() { };
|
revertObj = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePackNew>(response.Content);
|
if (revertObj.Code == null)
|
{
|
revertObj.Code = StateCode.DATA_EXCEPTION;
|
}
|
////统一转成大写
|
//revertObj.StateCode = revertObj.StateCode.ToUpper ();
|
return revertObj;
|
}
|
catch (Exception ex)
|
{
|
HDL_ON.Utlis.WriteLine(ex.Message);
|
return new ResponsePackNew() { Code = StateCode.DATA_EXCEPTION };
|
}
|
}
|
else
|
{
|
HDL_ON.Utlis.WriteLine(response.Content);
|
return new ResponsePackNew() { Code = StateCode.NETWORK_ERROR };
|
}
|
|
}
|
catch (Exception ex)
|
{
|
HDL_ON.Utlis.WriteLine(ex.Message);
|
return new ResponsePackNew() { Code = StateCode.NETWORK_ERROR };
|
}
|
|
#endregion
|
|
}
|
|
/// <summary>
|
/// 下载文件 请求服务器方法
|
/// </summary>
|
/// <param name="apiPath"></param>
|
/// <param name="bodyParameterJson"></param>
|
/// <param name="queryDictionary"></param>
|
/// <param name="urlHead"></param>
|
/// <param name="replaceToken"></param>
|
/// <param name="mTimeout"></param>
|
/// <returns></returns>
|
public static byte[] HttpsDownload(string requestFullUrl, int mTimeout = 30)
|
{
|
#region RestRequest
|
try
|
{
|
RestClient client = new RestClient(requestFullUrl);
|
RestRequest request = new RestRequest(Method.GET);
|
request.Timeout = mTimeout * 1000;
|
|
IRestResponse response = client.Execute(request);
|
return response.RawBytes;
|
}
|
catch (Exception ex)
|
{
|
HDL_ON.Utlis.WriteLine(ex.Message);
|
return null;
|
}
|
#endregion
|
|
}
|
|
#endregion
|
|
#region **********签名校验**********
|
/// <summary>
|
///
|
/// </summary>
|
const string APP_KEY = "HDL-HOME-APP-TEST";
|
/// <summary>
|
///
|
/// </summary>
|
const string SECRET_KEY = "WeJ8TY88vbakCcnvH8G1tDUqzLWY8yss";
|
|
/// <summary>
|
/// 获取当前时间戳值
|
/// </summary>
|
/// <returns></returns>
|
static string GetTimestamp()
|
{
|
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
|
return ((long)(DateTime.Now - startTime).TotalMilliseconds).ToString(); // 相差秒数
|
//return ((long)(DateTime.Now - startTime).TotalSeconds).ToString(); // 相差秒数
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="signstr"></param>
|
/// <returns></returns>
|
static string SignMD5Encrypt(string s)
|
{
|
byte[] sign = MD5.Create().ComputeHash(UTF8Encoding.UTF8.GetBytes(s));
|
string signstr = string.Empty;
|
foreach (byte item in sign)
|
{
|
signstr += item.ToString("X2");
|
}
|
return signstr.ToLower();
|
}
|
/// <summary>
|
/// 判断当前值是否需要参与签名,保持跟云端一致
|
/// 空字符串不参与
|
/// 数组,集合,对象不参与
|
/// </summary>
|
/// <param name="valueStr"></param>
|
/// <returns></returns>
|
static bool IfValueNeedSign(string valueStr)
|
{
|
if (string.IsNullOrEmpty(valueStr) || valueStr.StartsWith("{") || valueStr.StartsWith("["))
|
{
|
return false;
|
}
|
return true;
|
}
|
/// <summary>
|
/// 2020-11-02
|
/// 基础服务的接口都要校验sign
|
/// 计算sign签名
|
/// </summary>
|
/// <returns></returns>
|
public static string GetSignRequestJson(object requestObj,Dictionary<string,object> paramDictionary = null)
|
{
|
try
|
{
|
//1. 将model实体转为Dictionary<string, object>
|
if (paramDictionary == null)
|
{
|
paramDictionary = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(Newtonsoft.Json.JsonConvert.SerializeObject(requestObj));
|
}
|
//2. 计算sign
|
if (paramDictionary != null)
|
{
|
paramDictionary.Add("appKey", APP_KEY);
|
paramDictionary.Add("timestamp", GetTimestamp());
|
//2.1 字典升序
|
paramDictionary = paramDictionary.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
|
//2.2 拼接按URL键值对
|
string str = string.Empty;
|
foreach (KeyValuePair<string, object> item in paramDictionary)
|
{
|
//Value为null不参加校验
|
if (item.Value != null)
|
{
|
//Value.ToString()为null或者""也不参加校验
|
//if (!string.IsNullOrEmpty(item.Value.ToString()) && (item.Value is string || item.Value.GetType().IsValueType))
|
//{
|
//检测当前参数是否需要参与校验
|
if (IfValueNeedSign(item.Value.ToString()))
|
{
|
//如果是bool类型,要转小写
|
if (item.Value is bool)
|
{
|
str += item.Key + "=" + item.Value.ToString().ToLower() + "&";
|
}
|
else
|
{
|
str += item.Key + "=" + item.Value.ToString() + "&";
|
}
|
}
|
}
|
}
|
|
//2.3 拼接SECRET_KEY
|
str = str.Substring(0, str.Length - 1) + SECRET_KEY;
|
//2.4 MD5转换+转小写
|
var signstr = SignMD5Encrypt(str);
|
paramDictionary.Add("sign", signstr);
|
var signResult = Newtonsoft.Json.JsonConvert.SerializeObject(paramDictionary);
|
return signResult;
|
}
|
else
|
{
|
return "";
|
}
|
}
|
catch
|
{
|
return "";
|
}
|
}
|
|
#endregion
|
}
|
|
/// <summary>
|
/// 响应参数
|
/// </summary>
|
[Serializable]
|
public class ResponsePackNew
|
{
|
/// <summary>
|
/// 响应状态码
|
/// </summary>
|
public string Code;
|
|
/// <summary>
|
/// 响应内容
|
/// </summary>
|
public object Data;
|
|
/// <summary>
|
/// 响应错误信息
|
/// </summary>
|
public string message = "";
|
|
/// <summary>
|
/// 这个是请求错误时的扩展数据,以后所有的附带扩展数据都会放在这里面动态维护
|
/// </summary>
|
public object extra;
|
|
///// <summary>
|
///// isSuccess
|
///// </summary>
|
//public bool isSuccess;
|
|
///// <summary>
|
///// timestamp
|
///// </summary>
|
//public string timestamp;
|
|
|
}
|
|
}
|