/// <summary>
/// 通过JSON方式发送POST请求
/// 将返回结果按JSON方式解析
/// </summary>
public static class WebClientHelper
{
const string REQUEST_HEADER_BEARER = "bearer"; /// <summary>
/// 通过POST方式调用WEB API
/// 期待返回值为JSON字符串,并自动转换为期望的对象类型
/// 如果想直接获得原始的返回字符串,则T传为string
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="postData">post数据。自动转换为json格式,可以为空</param>
/// <param name="accessToken">调用FIDP API时,需要填写Access Token</param>
/// <returns></returns>
public static T Post<T>(string url, object postData, bool bNeedToken = true) where T : class
{
string accessToken = bNeedToken ? TokenCache.GetAccessToken() : null;
using (var wc = MyWebClient(accessToken))
{
string postJson = string.Empty;
if (postData != null) postJson = JsonConvert.SerializeObject(postData); string response = wc.UploadString(url, postJson);
if (typeof(T) == typeof(string)) return response as T;
T ret = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(response); return ret;
}
} /// <summary>
/// POST的异步版本
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="accessToken"></param>
/// <returns></returns>
public static async Task<T> PostAsync<T>(string url, object postData, bool bNeedToken = true) where T : class
{
string accessToken = bNeedToken ? TokenCache.GetAccessToken() : null;
using (var wc = MyWebClient(accessToken))
{
string postJson = string.Empty;
if (postData != null) postJson = JsonConvert.SerializeObject(postData); string response = await wc.UploadStringTaskAsync(url, postJson);
if (typeof(T) == typeof(string)) return response as T; T ret = JsonConvert.DeserializeObject<T>(response); return ret; }
} /// <summary>
/// 通过GET方式调用WEB API
/// 期待返回值为JSON字符串,并自动转换为期望的对象类型
/// 如果想直接获得原始的返回字符串,则T传为string
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="accessToken"></param>
/// <returns></returns>
public static T Get<T>(string url, bool bNeedToken = true) where T : class
{
string accessToken = bNeedToken ? TokenCache.GetAccessToken() : null;
using (var wc = MyWebClient(accessToken))
{
string response = wc.DownloadString(url); if (typeof(T) == typeof(string)) return response as T; T ret = JsonConvert.DeserializeObject<T>(response); return ret;
}
} public static string Get(string url, bool bNeedToken = true)
{
string accessToken = bNeedToken ? TokenCache.GetAccessToken() : null;
using (var wc = MyWebClient(accessToken))
{
string response = wc.DownloadString(url);
return response;
}
} /// <summary>
/// GET的异步版本
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="accessToken"></param>
/// <returns></returns>
public static async Task<T> GetAsync<T>(string url, bool bNeedToken = true) where T : class
{
string accessToken = bNeedToken ? TokenCache.GetAccessToken() : null;
using (var wc = MyWebClient(accessToken))
{
string response = await wc.DownloadStringTaskAsync(url); if (typeof(T) == typeof(string)) return response as T; T ret = JsonConvert.DeserializeObject<T>(response); return ret;
}
} private static WebClient MyWebClient(string accessToken)
{
var wc = new WebClient { Encoding = Encoding.UTF8 }; wc.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
wc.Headers.Add(HttpRequestHeader.Accept, "*/*");
wc.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
if (!string.IsNullOrEmpty(accessToken)) wc.Headers.Add(HttpRequestHeader.Authorization, REQUEST_HEADER_BEARER + " " + accessToken); return wc;
} /// <summary>
/// 上传文件
/// </summary>
/// <param name="url"></param>
/// <param name="file"></param>
/// <param name="bNeedToken"></param>
/// <returns></returns>
public static string UploadFile(string url, string file, bool bNeedToken = false)
{
string accessToken = bNeedToken ? TokenCache.GetAccessToken() : null;
using (var wc = MyWebClient(accessToken))
{
var b = wc.UploadFile(url, file);
return Encoding.UTF8.GetString(b);
}
} }
public class TokenCache
{
static TokenInfo tokenInfo = new TokenInfo();
static JwtCore jwtCore = new JwtCore(); static ICacheManager<TokenInfo> accessTokenCache = CacheFactory.FromConfiguration<TokenInfo>("tokenCache"); /// <summary>
/// SSO Clock Skew(秒):时钟调整,适配不同服务器之间的时钟偏差
/// </summary>
static readonly int CLOCK_SKEW_IN_SECONDS = int.Parse(ConfigurationManager.AppSettings["SSO:CLOCK_SKEW_IN_SECONDS"]); /// <summary>
/// AppInfo
/// </summary>
static readonly string AppId = ConfigurationManager.AppSettings["AppId"];
static readonly string AppSecret = ConfigurationManager.AppSettings["AppSecret"];
static public string GetAccessToken()
{
lock(tokenInfo)
{
return getAccessToken();
}
} static string getAccessToken()
{
string tokenKey = AppId; var ti = accessTokenCache.Get(tokenKey);
if(ti != null)
{
return ti.Token;
} // request a new access-token
string urlAccessToken = ApiConfig.Instance.GetUrl("sso.access_token");
Debug.Assert(!string.IsNullOrEmpty(urlAccessToken));
SSOAccessTokenReq req = new SSOAccessTokenReq()
{
AppId = AppId,
AppSecret = AppSecret,
//StoreCode,UserCode
}; //try
{
var ret = WebClientHelper.Post<ApiResultT<string>>(urlAccessToken, req, false);
if (ret.IsSuccess())
{
JwtPayload jwtPayload; var ret2 = jwtCore.ValidateToken(ret.data, out jwtPayload);
if (ret2.IsSuccess())
{
tokenInfo.Token = ret.data;
tokenInfo.ExpireAt = jwtPayload.exp; accessTokenCache.Add(tokenKey, tokenInfo); return tokenInfo.Token;
}
throw new Exception("Access Token 无效:" + ret2.ToString());
} throw new Exception("获取Access Token失败:" + ret.ToString());
}
//catch(WebException ex)
//{
// HttpWebResponse httpRep = ex.Response as HttpWebResponse;
// if (httpRep != null)
// {
// if(httpRep.StatusCode == HttpStatusCode.Forbidden)
// { // } // }
//} } internal class TokenInfo
{
public string Token { get; set; } /// <summary>
/// 到期时间:Unix Timestamp
/// </summary>
public long ExpireAt { get; set; }
} }