????????組件開始設(shè)計(jì)是針對(duì)以接口的方式來(lái)定義HTTP/HTTPS訪問(wèn),雖然基于接口來(lái)操作有很大的便利性,但定義起來(lái)就比較麻煩了。所以在1.5版本中實(shí)現(xiàn)了一個(gè)HttpClient類來(lái)簡(jiǎn)化調(diào)用。
HttpClient ????????該類支持HTTP的GET,POST,DELETE和PUT操作,通過(guò)這幾個(gè)方法可以調(diào)用HTTP請(qǐng)求,包括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();}}
以上是類的完全整代碼實(shí)現(xiàn),代碼量比較少歸功于組件在基礎(chǔ)上的基礎(chǔ)封裝。為了更方便使用組件在這基礎(chǔ)上擴(kuò)展了幾種常用格式調(diào)用Client類。
????//二進(jìn)制流處理,下載文件public class HttpBinaryClient : HttpClient<BinaryFormater>{public HttpBinaryClient(string host) : base(host){}}//常用的Form?url?encoding編碼,對(duì)應(yīng)application/x-www-form-urlencodedpublic class HttpFormUrlClient : HttpClient<FormUrlFormater>{public HttpFormUrlClient(string host) : base(host){}}//用于json請(qǐng)求響應(yīng),對(duì)應(yīng)application/jsonpublic class HttpJsonClient : HttpClient<JsonFormater>{public HttpJsonClient(string host) : base(host){}}//等價(jià)于multipart/form-data,常用于上傳文件public class HttpFormDataClient : HttpClient<FromDataFormater>{public HttpFormDataClient(string host) : base(host){}}
可以根據(jù)自己需要來(lái)使用不同的Client。
自定義Formater
????????有很多時(shí)候請(qǐng)求和響應(yīng)的內(nèi)容不一致,這個(gè)時(shí)候就要用到自定義Formater了,組件支持這樣的擴(kuò)展,只需要FormaterAttribute對(duì)象重寫相關(guān)方法即可。以下是BinaryFormater的擴(kuò)展:
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>");}}}
為了方便也可以繼承已經(jīng)實(shí)現(xiàn)的,重寫單個(gè)方法。
使用
? ? ? ? ?在使用之前需要引用BeetleX.Http.Clients,引用后即可使用組件來(lái)訪問(wèn)HTTP/HTTPS服務(wù)。
[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();}}
以上是組件的一些用例應(yīng)用代碼。
總結(jié)
以上是生活随笔 為你收集整理的BeetleX.Http.Clients V1.5发布 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。