У меня есть консольное / winform (не браузерное) приложение, которое использует ASP. NET Web API. Я реализовал аутентификацию на основе токенов, чтобы защитить свои веб-интерфейсы, и мне нужно выяснить, где лучше всего получить токен, если я следовал шаблону хранилища с использованием класса HttpClientHelper
?
Чтобы получить токен:
private static string GetToken(string url, string userName, string password)
{
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>( "grant_type", "password" ),
new KeyValuePair<string, string>( "username", userName ),
new KeyValuePair<string, string> ( "Password", password )
};
var content = new FormUrlEncodedContent(pairs);
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
using(var client = new HttpClient())
{
var response = client.PostAsync(url + "Token", content).Result;
return response.Content.ReadAsStringAsync().Result;
}
}
Помощник HttpClient:
public sealed class HttpClientHelper<T, TResourceIdentifier> : IDisposable where T : class
{
#region Constructors
public HttpClientHelper(string serviceBaseAddress, string addressSuffix, string token)
{
_serviceBaseAddress = serviceBaseAddress;
_addressSuffix = addressSuffix;
_token = token
_httpClient = MakeHttpClient();
}
#endregion
#region CRUD
public async Task<IEnumerable<T>> GetManyAsync()
{
var responseMessage = await _httpClient.GetAsync(_addressSuffix);
if (responseMessage.IsSuccessStatusCode)
return await responseMessage.Content.ReadAsAsync<IEnumerable<T>>();
return null;
}
// Other CRUD operations
#endregion
#region Private Methods
private HttpClient MakeHttpClient()
{
_httpClient = new HttpClient
{
BaseAddress = new Uri(_serviceBaseAddress),
MaxResponseContentBufferSize = int.MaxValue,
DefaultRequestHeaders = {Authorization = new AuthenticationHeaderValue("bearer", token)}
};
// Other settings
return _httpClient;
}
#region IDisposable Members
private void Dispose(bool disposing)
{
if (_disposed || !disposing) return;
if (_httpClient != null)
{
var hc = _httpClient;
_httpClient = null;
hc.Dispose();
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~HttpClientHelper()
{
Dispose(false);
}
#endregion IDisposable Members
}
}
Мой универсальный c класс:
internal class GenericRepository<T, TResourceIdentifier> : IDisposable, IGenericRepository<T, TResourceIdentifier> where T : class
{
private bool _disposed;
protected HttpClientHelper<T, TResourceIdentifier> Client;
protected GenericRepository(string serviceBaseAddress, string addressSuffix, string token)
{
Client = new HttpClientHelper<T, TResourceIdentifier>(serviceBaseAddress, addressSuffix, token);
}
public async Task<IEnumerable<T>> GetManyAsync()
{
return await Client.GetManyAsync();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (_disposed || !disposing) return;
if (Client != null)
{
var mc = Client;
Client = null;
mc.Dispose();
}
_disposed = true;
}
}
Пример пользовательского класса репозитория:
internal class CustomerRepository : GenericRepository<Customer, int> , ICustomerRepository
{
internal CustomerRepository() : base(Properties.Settings.Default.Url, "Customers/", ***TOKEN***)
{
}
}
Использование:
private readonly ICustomerRepository _customerRepository = new CustomerRepository();
private async Task<Customer> GetCustomer(int customerId)
{
var customer = new Customer();
try
{
customer = await _customerRepository.GetAsync(customerId);
}
catch (Exception ex)
{
// Log the error
}
return customer;
}
Где именно я могу получить / назначить токен без получения ошибки nullexception при объявлении моего IRepository?