目前在Startup.cs中,我有:
services.AddSingleton<IApiClient>(new ApiClient(Configuration.GetValue<string>("WebApiBaseAddress")));
我有一个APIClient:
public class ApiClient : IApiClient
{
private readonly HttpClient _client;
private readonly JsonMediaTypeFormatter _formatter;
/// <summary>
/// The ApiClient constructor.
/// </summary>
public ApiClient(string baseAddress)
{
_client = new HttpClient { BaseAddress = new Uri(baseAddress) };
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//_client.DefaultRequestHeaders.Add("Authorization", "Bearer " + apiToken);
_formatter = new JsonMediaTypeFormatter();
_formatter.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
}
/// <summary>
/// Fetches the list of <see cref="TModel"/>.
/// </summary>
/// <typeparam name="TModel">Model's type.</typeparam>
/// <param name="path">The uri path.</param>
/// <returns>List of <see cref="TModel"/>.</returns>
public async Task<IList<TModel>> Get<TModel>(string path)
{
return await Get<TModel>(path, null);
}
public async Task<TModel> GetObject<TModel>(string path)
{
// todo : use parameters
var response = await _client.GetStringAsync($"{path}");
var result = JsonConvert.DeserializeObject<TModel>(response);
return result;
}
/// <summary>
/// Fetches the list of <see cref="TModel"/>.
/// </summary>
/// <typeparam name="TModel">Model's type.</typeparam>
/// <param name="path">The uri path.</param>
/// <param name="parameters">The uri parameters.</param>
/// <returns>The list of <see cref="TModel"/>.</returns>
private async Task<IList<TModel>> Get<TModel>(string path, IDictionary<string, string> parameters)
{
// todo : use parameters
var response = await _client.GetStringAsync($"{path}");
var result = JsonConvert.DeserializeObject<IList<TModel>>(response);
return result;
}
/// <summary>
/// Fetches the <see cref="TModel"/>.
/// </summary>
/// <typeparam name="TModel">Model's type.</typeparam>
/// <param name="path">The uri path.</param>
/// <param name="id">Unique identifier of the model.</param>
/// <param name="afterPath">The uri path after id.</param>
/// <returns>The <see cref="TModel"/> model.</returns>
public async Task<TModel> Get<TModel>(string path, object id, string afterPath = null)
{
var response = await _client.GetStringAsync($"{path}/{id}{afterPath}");
var result = JsonConvert.DeserializeObject<TModel>(response);
return result;
}
/// <summary>
/// Creates the <see cref="TModel"/> model.
/// </summary>
/// <typeparam name="TModel">Model's type.</typeparam>
/// <param name="path">The uri path.</param>
/// <param name="model">The model.</param>
public async Task<HttpResponseMessage> Post<TModel>(string path, TModel model)
{
HttpContent content = new ObjectContent<TModel>(model, _formatter);
return await _client.PostAsync($"{path}", content);
}
/// <summary>
/// Updates the <see cref="TModel"/> model.
/// </summary>
/// <typeparam name="TModel">Model's type.</typeparam>
/// <param name="path">The uri path.</param>
/// <param name="id">Unique identifier of the model.</param>
/// <param name="model">The model.</param>
public async Task<HttpResponseMessage> Put<TModel>(string path, object id, TModel model)
{
HttpContent content = new ObjectContent<TModel>(model, _formatter);
return await _client.PutAsync($"{path}/{id}", content);
}
/// <summary>
/// Partially update the model
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <param name="path"></param>
/// <param name="id"></param>
/// <param name="model"></param>
/// <returns></returns>
public async Task<HttpResponseMessage> Patch<TModel>(string path, object id, TModel model)
{
JsonPatchDocument patchDoc = new JsonPatchDocument();
foreach (PropertyInfo propInfo in model.GetType().GetProperties())
{
var value = propInfo.GetValue(model);
if (value == null) continue;
patchDoc.Replace(propInfo.Name, value);
}
var serializedPatchItem = JsonConvert.SerializeObject(patchDoc);
var method = new HttpMethod("PATCH");
var request = new HttpRequestMessage(method, $"{path}/{id}")
{
Content = new StringContent(serializedPatchItem, System.Text.Encoding.Unicode, "application/json")
};
return await _client.SendAsync(request);
}
/// <summary>
/// Deletes the model.
/// </summary>
/// <param name="path">The uri path.</param>
/// <param name="id">Unique identifier of the model.</param>
public async Task<HttpResponseMessage> Delete(string path, object id)
{
return await _client.DeleteAsync($"{path}/{id}");
}
}
}
我有一个APIClient接口:
public interface IApiClient
{
/// <summary>
/// Fetches the list of <see cref="TModel"/>.
/// </summary>
/// <typeparam name="TModel">Model's type.</typeparam>
/// <param name="path">The uri path.</param>
/// <returns>List of <see cref="TModel"/>.</returns>
Task<IList<TModel>> Get<TModel>(string path);
//
Task<TModel> GetObject<TModel>(string path);
/// <summary>
/// Fetches the <see cref="TModel"/>.
/// </summary>
/// <typeparam name="TModel">Model's type.</typeparam>
/// <param name="path">The uri path.</param>
/// <param name="id">Unique identifier of the model.</param>
/// <param name="afterPath">The uri path after id.</param>
/// <returns>The <see cref="TModel"/> model.</returns>
Task<TModel> Get<TModel>(string path, object id, string afterPath = null);
/// <summary>
/// Creates the <see cref="TModel"/> model.
/// </summary>
/// <typeparam name="TModel">Model's type.</typeparam>
/// <param name="path">The uri path.</param>
/// <param name="model">The model.</param>
Task<HttpResponseMessage> Post<TModel>(string path, TModel model);
/// <summary>
/// Updates the <see cref="TModel"/> model.
/// </summary>
/// <typeparam name="TModel">Model's type.</typeparam>
/// <param name="path">The uri path.</param>
/// <param name="id">Unique identifier of the model.</param>
/// <param name="model">The model.</param>
Task<HttpResponseMessage> Put<TModel>(string path, object id, TModel model);
/// <summary>
/// Partially updates the model
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <param name="path"></param>
/// <param name="id"></param>
/// <param name="model"></param>
/// <returns></returns>
Task<HttpResponseMessage> Patch<TModel>(string path, object id, TModel model);
/// <summary>
/// Deletes the model.
/// </summary>
/// <param name="path">The uri path.</param>
/// <param name="id">Unique identifier of the model.</param>
Task<HttpResponseMessage> Delete(string path, object id);
}
因此,此刻将在启动时使用配置中的基址创建APIClient。
我想在运行时将另一个名为ApiToken的值传递给APIClient,并在用户成功登录后从我的登录控制器将其添加为Authorization标头。
我将从Auth控制器返回的API令牌存储在以下位置:
new Claim("Token", loggedInUser.ApiToken.ToString())
我将APIClient更改为:
public ApiClient(string baseAddress, string apiToken)
但是随着它在一开始就设置好,我不清楚用户登录后如何在运行时进行设置。
有人可以给我一些指示吗?