diff --git a/HackMD.API/HackMD.API.csproj b/HackMD.API/HackMD.API.csproj
index 9a41e29..c3092cd 100644
--- a/HackMD.API/HackMD.API.csproj
+++ b/HackMD.API/HackMD.API.csproj
@@ -17,4 +17,8 @@ https://github.com/isdaviddong/HackMD.API
https://github.com/isdaviddong/HackMD.API
+
+
+
+
diff --git a/HackMD.API/HackMDClinet.cs b/HackMD.API/HackMDClinet.cs
index c97f8a1..dbb4a0b 100644
--- a/HackMD.API/HackMDClinet.cs
+++ b/HackMD.API/HackMDClinet.cs
@@ -1,6 +1,10 @@
using System;
using System.Net.Http;
+using System.Net.Http.Headers;
using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
namespace HackMD.API
{
@@ -8,85 +12,113 @@ public class HackMDClient
{
private string token;
- public string Token
+ private static readonly Lazy s_socketLazy = new Lazy(() =>
{
- get { return token; }
- set { token = value; }
- }
+ var socketsHandler = new SocketsHttpHandler
+ {
+ PooledConnectionLifetime = TimeSpan.FromMinutes(10),
+ PooledConnectionIdleTimeout = TimeSpan.FromMinutes(5),
+ MaxConnectionsPerServer = 10
+ };
+ return socketsHandler;
+ });
+
+ private readonly string _token;
public HackMDClient(string token)
{
- this.Token = token;
+ this._token = token;
+ }
+
+ static HttpClient CreateHttpClient(string token)
+ {
+ return new HttpClient(s_socketLazy.Value)
+ {
+ DefaultRequestHeaders =
+ {
+ Authorization = new AuthenticationHeaderValue(JwtBearerDefaults.AuthenticationScheme,
+ token)
+ },
+ BaseAddress = new Uri("https://api.hackmd.io/v1/")
+ };
}
- private string endpoint = "https://api.hackmd.io/v1/";
#region "User API"
- public User GetUserInformation()
+
+ public User GetUserInformation() => this.GetUserInformationAsync().Result;
+
+ public async Task GetUserInformationAsync(CancellationToken cancel = default)
{
- HttpClient client = new HttpClient();
- string uri = endpoint + $"/me";
-
- // Request headers.
- client.DefaultRequestHeaders.Add("Authorization", $"Bearer {this.Token}");
- var response = client.GetAsync(uri).Result;
- var ResponseBody = response.Content.ReadAsStringAsync().Result;
- var UserObj = System.Text.Json.JsonSerializer.Deserialize(ResponseBody);
- return UserObj;
+ var client = CreateHttpClient(this._token);
+ string uri = "me";
+
+ var request = CreateDefaultHttpRequest(token, uri);
+ var response = await client.SendAsync(request, cancel);
+ var responseBody = await response.Content.ReadAsStringAsync();
+ var result = System.Text.Json.JsonSerializer.Deserialize(responseBody);
+ return result;
}
+
#endregion
#region "User Notes API"
+
///
/// Create a note
///
///
///
- public NoteResponse CreateNote(Note newHackMDNote)
+ public NoteResponse CreateNote(Note newHackMDNote) => this.CreateNoteAsync(newHackMDNote).Result;
+
+ public async Task CreateNoteAsync(Note newHackMDNote, CancellationToken cancel = default)
{
- HttpClient client = new HttpClient();
- string uri = endpoint + "/notes";
+ var client = CreateHttpClient(this._token);
+ string uri = "notes";
+
+ var requestBody = System.Text.Json.JsonSerializer.Serialize(newHackMDNote);
+ var requestContent = new StringContent(requestBody, Encoding.UTF8, "application/json");
- // Request headers.
- client.DefaultRequestHeaders.Add("Authorization", $"Bearer {this.Token}");
- var JSON = System.Text.Json.JsonSerializer.Serialize(newHackMDNote);
- var content = new StringContent(JSON, Encoding.UTF8, "application/json");
// Asynchronously call the REST API method.
- var response = client.PostAsync(uri, content).Result;
- var ResponseBody = response.Content.ReadAsStringAsync().Result;
- var CreateNoteResponseObj = System.Text.Json.JsonSerializer.Deserialize(ResponseBody);
- return CreateNoteResponseObj;
+ var response = await client.PostAsync(uri, requestContent, cancel);
+ var responseBody = await response.Content.ReadAsStringAsync();
+ var result = System.Text.Json.JsonSerializer.Deserialize(responseBody);
+ return result;
}
- public NoteResponse GetNote(string noteId)
+
+ public NoteResponse GetNote(string noteId) => this.GetNoteAsync(noteId).Result;
+
+ public async Task GetNoteAsync(string noteId)
{
- HttpClient client = new HttpClient();
- string uri = endpoint + $"/notes/{noteId}";
-
- // Request headers.
- client.DefaultRequestHeaders.Add("Authorization", $"Bearer {this.Token}");
- var response = client.GetAsync(uri).Result;
- var ResponseBody = response.Content.ReadAsStringAsync().Result;
- var CreateNoteResponseObj = System.Text.Json.JsonSerializer.Deserialize(ResponseBody);
- return CreateNoteResponseObj;
+ var client = CreateHttpClient(this._token);
+ string uri = $"notes/{noteId}";
+
+ var response = await client.GetAsync(uri);
+ var responseBody = await response.Content.ReadAsStringAsync();
+ var result = System.Text.Json.JsonSerializer.Deserialize(responseBody);
+ return result;
}
- public bool UpdateNote(string noteId, string content, ReadWritePermission readPermission, ReadWritePermission writePermission, string permalink)
+
+ public bool UpdateNote(string noteId, string content, ReadWritePermission readPermission,
+ ReadWritePermission writePermission, string permalink) =>
+ this.UpdateNoteAsync(noteId, content, readPermission, writePermission, permalink).Result;
+
+ public async Task UpdateNoteAsync(string noteId, string content, ReadWritePermission readPermission,
+ ReadWritePermission writePermission, string permalink)
{
- HttpClient client = new HttpClient();
- string uri = endpoint + $"/notes/{noteId}";
+ var client = CreateHttpClient(this._token);
+
+ string uri = $"notes/{noteId}";
- var obj = new
+ var requestBody = System.Text.Json.JsonSerializer.Serialize(new
{
- content = content,
+ content,
readPermission = readPermission.ToString(),
writePermission = writePermission.ToString(),
- permalink = permalink
- };
-
- // Request headers.
- client.DefaultRequestHeaders.Add("Authorization", $"Bearer {this.Token}");
- var JSON = System.Text.Json.JsonSerializer.Serialize(obj);
- var body = new StringContent(JSON, Encoding.UTF8, "application/json");
- var response = client.PatchAsync(uri, body).Result;
- var ResponseBody = response.Content.ReadAsStringAsync().Result;
+ permalink
+ });
+ var requestContent = new StringContent(requestBody, Encoding.UTF8, "application/json");
+ var response = await client.PatchAsync(uri, requestContent);
+ var responseBody = await response.Content.ReadAsStringAsync();
return response.StatusCode == System.Net.HttpStatusCode.Accepted;
}
@@ -95,17 +127,25 @@ public bool UpdateNote(string noteId, string content, ReadWritePermission readPe
///
///
///
- public bool DeleteNote(string noteId)
+ public bool DeleteNote(string noteId) => this.DeleteNoteAsync(noteId).Result;
+
+ public async Task DeleteNoteAsync(string noteId)
{
- HttpClient client = new HttpClient();
- string uri = endpoint + $"/notes/{noteId}";
+ var client = CreateHttpClient(this._token);
- // Request headers.
- client.DefaultRequestHeaders.Add("Authorization", $"Bearer {this.Token}");
+ string uri = $"notes/{noteId}";
- var response = client.DeleteAsync(uri).Result;
+ var response = await client.DeleteAsync(uri);
return response.StatusCode == System.Net.HttpStatusCode.NoContent;
}
+
#endregion
+
+ private static HttpRequestMessage CreateDefaultHttpRequest(string token, string uri)
+ {
+ var request = new HttpRequestMessage(HttpMethod.Get, uri);
+ request.Headers.Add("Authorization", $"Bearer {token}");
+ return request;
+ }
}
-}
+}
\ No newline at end of file
diff --git a/HackMD.APITests/HackMDClinetTests.cs b/HackMD.APITests/HackMDClinetTests.cs
index 266bf52..df38f2c 100644
--- a/HackMD.APITests/HackMDClinetTests.cs
+++ b/HackMD.APITests/HackMDClinetTests.cs
@@ -1,8 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using HackMD.API;
using System;
-using System.Collections.Generic;
-using System.Text;
namespace HackMD.API.Tests
{
@@ -25,7 +22,7 @@ public HackMDClientTests()
public void CreateNoteTest()
{
// 建立HackMDClient 物件
- HackMDClient c = new HackMDClient(token); //須提供token
+ HackMDClient c = new HackMDClient(this.token); //須提供token
//建立新 Note
var ret = c.CreateNote(
new Note()
@@ -39,14 +36,14 @@ public void CreateNoteTest()
//取得 NoteId
TempNoteId = ret.id;
Assert.IsTrue(!string.IsNullOrEmpty(ret.id));
- //c.DeleteNote(ret.id);
+ // c.DeleteNote(ret.id);
}
[TestMethod()]
public void DeleteNoteTest()
{
// 建立HackMDClient 物件
- HackMDClient c = new HackMDClient(token); //須提供token
+ HackMDClient c = new HackMDClient(this.token); //須提供token
var ret = c.CreateNote(
new Note()
{
@@ -67,7 +64,7 @@ public void DeleteNoteTest()
public void UpdateNoteTest()
{
// 建立HackMDClient 物件
- HackMDClient c = new HackMDClient(token); //須提供token
+ HackMDClient c = new HackMDClient(this.token); //須提供token
var ret = c.CreateNote(
new Note()
{
@@ -94,7 +91,7 @@ public void UpdateNoteTest()
public void GetNoteTest()
{
// 建立HackMDClient 物件
- HackMDClient c = new HackMDClient(token); //須提供token
+ HackMDClient c = new HackMDClient(this.token); //須提供token
//建立文件
var ret = c.CreateNote(
new Note()