I've used a custom wrapper for calling asp.net web API services in some projects. I just wanted to share it over here. It's been tested for hundreds of times!
public class MyCustomWrapper<T> where T : class
{
private static readonly HttpClient Client = new HttpClient();
public async Task<T> GetItemAsync(string apiUrl, CancellationToken cancellationToken)
{
var result = default(T);
try
{
var response = await Client.GetAsync(apiUrl, cancellationToken).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
await response.Content.ReadAsStringAsync().ContinueWith(x =>
{
if (typeof(T).Namespace != "System")
{
var data = x?.Result;
result = JsonConvert.DeserializeObject<T>(data);
}
else result = (T)Convert.ChangeType(x?.Result, typeof(T));
}, cancellationToken);
}
else
{
var content = await response.Content.ReadAsStringAsync();
response.Content?.Dispose();
throw new HttpRequestException($"{response.StatusCode}:{content}");
}
}
catch (Exception)
{
return result;
}
return result;
}
public async Task<T[]> GetItemsRequestAsync(string apiUrl, CancellationToken cancellationToken)
{
T[] result = null;
var response = await Client.GetAsync(apiUrl, cancellationToken).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
await response.Content.ReadAsStringAsync().ContinueWith((Task<string> x) =>
{
result = JsonConvert.DeserializeObject<T[]>(x.Result);
}, cancellationToken);
}
else
{
var content = await response.Content.ReadAsStringAsync();
response.Content?.Dispose();
throw new HttpRequestException($"{response.StatusCode}:{content}");
}
return result;
}
public async Task<T> PostRequestAsync(string apiUrl, T postObject, CancellationToken cancellationToken)
{
T result = default(T);
var json = JsonConvert.SerializeObject(postObject);
var content = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
var response = await Client.PostAsync(apiUrl, content);
if (response.IsSuccessStatusCode)
{
await response.Content.ReadAsStringAsync().ContinueWith((Task<string> x) =>
{
result = JsonConvert.DeserializeObject<T>(x.Result);
}, cancellationToken);
}
else
{
var unSuccesscontent = await response.Content.ReadAsStringAsync();
response.Content?.Dispose();
throw new HttpRequestException($"{response.StatusCode}:{unSuccesscontent}");
}
return result;
}
public async Task PutRequestAsync(string apiUrl, T putObject, CancellationToken cancellationToken)
{
var response = await Client.PutAsync(apiUrl, new JsonContent(putObject), cancellationToken).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
response.Content?.Dispose();
throw new HttpRequestException($"{response.StatusCode}:{content}");
}
}
public async Task DeleteRequestAsync(string apiUrl, CancellationToken cancellationToken)
{
var response = await Client.DeleteAsync(apiUrl, cancellationToken).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
var content = response.Content.ReadAsStringAsync();
response.Content?.Dispose();
throw new HttpRequestException($"{response.StatusCode}:{content}");
}
}
}
public class JsonContent : StringContent
{
public static JsonContent From(object data) => data == null ? null : new JsonContent(data);
public JsonContent(object data)
: base(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")
{
}
}
And about the usage of this wrapper:
var wrapperResult = new MyCustomWrapper<YourClass>();
var result = wrapperResult.GetItemAsync("https://localhost/api/user/GetInfo?username=" + "userName", new CancellationToken());
var data = result.Result;
that's it!