????????組件開始設計是針對以接口的方式來定義HTTP/HTTPS訪問,雖然基于接口來操作有很大的便利性,但定義起來就比較麻煩了。所以在1.5版本中實現了一個HttpClient類來簡化調用。
HttpClient ????????該類支持HTTP的GET,POST,DELETE和PUT操作,通過這幾個方法可以調用HTTP請求,包括application/json和上傳文件等。
public class HttpClient<T>where T : IBodyFormater, new(){public HttpClient(string host){mHost = HttpHost.GetHttpHost(host);}private HttpHost mHost;private Dictionary<string, string> mQueryString = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);private Dictionary<string, string> mHeader = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);private object mDataObject;private Dictionary<string, object> mDataMap = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);public HttpClient<T> Accept(string value){mHeader["accept"] = value;return this;}public HttpClient<T> Authorization(string value){mHeader["authorization"] = value;return this;}public HttpClient<T> SetHeader(string name, string value){mHeader[name] = value;return this;}public HttpClient<T> AddQueryString(string name, object value){mQueryString[name] = value.ToString();return this;}public HttpClient<T> SetBody(object data){mDataObject = data;return this;}public HttpClient<T> AddBodyFile(string name, string file){AddBodyField(name, new FileInfo(file));return this;}public HttpClient<T> AddBodyFile(string name, UploadFile file){AddBodyField(name, file);return this;}public HttpClient<T> AddBodyField(string name, object data){mDataMap[name] = data;return this;}public async Task<RESULT> Get<RESULT>(string url){var response = await Get(url, typeof(RESULT));return response.GetResult<RESULT>();}public Task<Response> Get(string url, Type bodyType = null){var request = mHost.Get(url, mHeader, mQueryString, new T(), bodyType);return request.Execute();}public async Task<RESULT> Post<RESULT>(string url){var response = await Post(url, typeof(RESULT));return response.GetResult<RESULT>();}public Task<Response> Post(string url, Type bodyType = null){var request = mHost.Post(url, mHeader, mQueryString, mDataObject == null ? mDataMap : mDataObject, new T(), bodyType);return request.Execute();}public async Task<RESULT> Put<RESULT>(string url){var response = await Put(url, typeof(RESULT));return response.GetResult<RESULT>();}public Task<Response> Put(string url, Type bodyType = null){var request = mHost.Put(url, mHeader, mQueryString, mDataObject == null ? mDataMap : mDataObject, new T(), bodyType);return request.Execute();}public async Task<RESULT> Delete<RESULT>(string url){var response = await Delete(url, typeof(RESULT));return response.GetResult<RESULT>();}public Task<Response> Delete(string url, Type bodyType = null){var request = mHost.Delete(url, mHeader, mQueryString, new T(), bodyType);return request.Execute();}}
以上是類的完全整代碼實現,代碼量比較少歸功于組件在基礎上的基礎封裝。為了更方便使用組件在這基礎上擴展了幾種常用格式調用Client類。
????//二進制流處理,下載文件public class HttpBinaryClient : HttpClient<BinaryFormater>{public HttpBinaryClient(string host) : base(host){}}//常用的Form?url?encoding編碼,對應application/x-www-form-urlencodedpublic class HttpFormUrlClient : HttpClient<FormUrlFormater>{public HttpFormUrlClient(string host) : base(host){}}//用于json請求響應,對應application/jsonpublic class HttpJsonClient : HttpClient<JsonFormater>{public HttpJsonClient(string host) : base(host){}}//等價于multipart/form-data,常用于上傳文件public class HttpFormDataClient : HttpClient<FromDataFormater>{public HttpFormDataClient(string host) : base(host){}}
可以根據自己需要來使用不同的Client。
自定義Formater
????????有很多時候請求和響應的內容不一致,這個時候就要用到自定義Formater了,組件支持這樣的擴展,只需要FormaterAttribute對象重寫相關方法即可。以下是BinaryFormater的擴展:
public class BinaryFormater : FormaterAttribute{public override string ContentType => "application/octet-stream";public override object Deserialization(Response response, PipeStream stream, Type type, int length){var result = System.Buffers.ArrayPool<byte>.Shared.Rent(length);stream.Read(result, 0, length);return new ArraySegment<Byte>(result, 0, length);}public override void Serialization(Request request, object data, PipeStream stream){if (data is Byte[] buffer){stream.Write(buffer, 0, buffer.Length);}else if (data is ArraySegment<byte> array){stream.Write(array.Array, array.Offset, array.Count);}else{throw new Exception("Commit data must be byte[] or ArraySegment<byte>");}}}
為了方便也可以繼承已經實現的,重寫單個方法。
使用
? ? ? ? ?在使用之前需要引用BeetleX.Http.Clients,引用后即可使用組件來訪問HTTP/HTTPS服務。
[Fact]public async Task HttpBin_Delete(){HttpJsonClient client = new HttpJsonClient("http://httpbin.org");var result = await client.Delete("/delete");Assert.Equal(null, result.Exception);}[Fact]public async Task HttpBin_Get(){HttpJsonClient client = new HttpJsonClient("http://httpbin.org");var result = await client.Get("/get");Assert.Equal(null, result.Exception);}[Fact]public async Task HttpBin_Post(){HttpJsonClient client = new HttpJsonClient("http://httpbin.org");var date = DateTime.Now;client.SetBody(date);var result = await client.Post("/post");JToken?rdata?=?result.GetResult<JToken>()["data"];}[Fact]public async Task HttpBin_Put(){HttpJsonClient client = new HttpJsonClient("http://httpbin.org");Employee emp = DataHelper.Defalut.Employees[0];client.SetBody(emp);var result = await client.Post("/post");JToken?rdata?=?result.GetResult<JToken>()["data"];}[Fact]public async Task GetImage(){HttpClient<BinaryFormater> client = new HttpClient<BinaryFormater>("http://httpbin.org");var result = await client.Get("/image");var data = result.GetResult<ArraySegment<byte>>();using (System.IO.Stream write = System.IO.File.Create("test.jpg")){write.Write(data.Array, data.Offset, data.Count);write.Flush();}}
以上是組件的一些用例應用代碼。
總結
以上是生活随笔 為你收集整理的BeetleX.Http.Clients V1.5发布 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。