WebClient请求帮助类
/// <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; } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2015-04-16 async & await 的前世今生