Ajustes para trasmitir expedientes
This commit is contained in:
@@ -20,6 +20,7 @@ namespace EFCDesk.Classes
|
||||
|
||||
public class ApiClient : IDisposable
|
||||
{
|
||||
private static readonly HttpClient _sharedHttpClient = new HttpClient();
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly int _maxRetries;
|
||||
private readonly TimeSpan _retryDelay;
|
||||
@@ -30,12 +31,10 @@ public class ApiClient : IDisposable
|
||||
|
||||
public ApiClient(TimeSpan? timeout = null, int maxRetries = 3, TimeSpan? retryDelay = null)
|
||||
{
|
||||
_httpClient = new HttpClient();
|
||||
_httpClient = _sharedHttpClient;
|
||||
|
||||
if (timeout.HasValue)
|
||||
if (timeout.HasValue && timeout.Value > _httpClient.Timeout)
|
||||
_httpClient.Timeout = timeout.Value;
|
||||
else
|
||||
_httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||
|
||||
_maxRetries = maxRetries >= 0 ? maxRetries : 3;
|
||||
_retryDelay = retryDelay ?? TimeSpan.FromSeconds(2);
|
||||
@@ -98,12 +97,14 @@ public class ApiClient : IDisposable
|
||||
var jsonContent = JsonSerializer.Serialize(refreshData);
|
||||
|
||||
using var content = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
|
||||
// Limpiar headers para esta solicitud
|
||||
_httpClient.DefaultRequestHeaders.Authorization = null;
|
||||
|
||||
var response = await _httpClient.PostAsync(refreshUrl, content);
|
||||
|
||||
// _httpClient.DefaultRequestHeaders.Authorization = null;
|
||||
// var response = await _httpClient.PostAsync(refreshUrl, content);
|
||||
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, refreshUrl) { Content = content };
|
||||
var response = await _httpClient.SendAsync(request);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
string responseContent = await response.Content.ReadAsStringAsync();
|
||||
@@ -191,7 +192,7 @@ public class ApiClient : IDisposable
|
||||
}
|
||||
|
||||
|
||||
private async Task<string> SendWithRetriesAsync(Func<Task<HttpResponseMessage>> sendFunc, bool requireAuth = true)
|
||||
private async Task<string> SendWithRetriesAsync(Func<HttpRequestMessage> requestFunc, bool requireAuth = true)
|
||||
{
|
||||
int attempts = 0;
|
||||
while (true)
|
||||
@@ -199,40 +200,61 @@ public class ApiClient : IDisposable
|
||||
attempts++;
|
||||
try
|
||||
{
|
||||
// Asegurar que tenemos token antes de enviar (solo si requiere auth)
|
||||
string? token = null;
|
||||
|
||||
if (requireAuth)
|
||||
{
|
||||
await EnsureTokenAsync();
|
||||
lock (_tokenLock)
|
||||
{
|
||||
token = _currentToken;
|
||||
}
|
||||
}
|
||||
|
||||
var response = await sendFunc();
|
||||
var request = requestFunc();
|
||||
|
||||
if (requireAuth && token != null)
|
||||
{
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
}
|
||||
|
||||
var response = await _httpClient.SendAsync(request);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
// Si es 401 Unauthorized y requiere auth, intentar refresh token
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized && requireAuth)
|
||||
{
|
||||
bool refreshed = await TryRefreshTokenAsync();
|
||||
if (refreshed)
|
||||
{
|
||||
// Reintentar con nuevo token
|
||||
response = await sendFunc();
|
||||
string? newToken = null;
|
||||
lock (_tokenLock)
|
||||
{
|
||||
newToken = _currentToken;
|
||||
}
|
||||
|
||||
var newRequest = requestFunc();
|
||||
if (newToken != null)
|
||||
{
|
||||
newRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", newToken);
|
||||
}
|
||||
|
||||
response = await _httpClient.SendAsync(newRequest);
|
||||
if (response.IsSuccessStatusCode)
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
}
|
||||
|
||||
string errorContent = await response.Content.ReadAsStringAsync();
|
||||
// throw new ApiException($"Error {response.StatusCode}: {errorContent}", (int)response.StatusCode);
|
||||
return errorContent;
|
||||
}
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
catch (TaskCanceledException) when (attempts <= _maxRetries)
|
||||
{
|
||||
// Timeout: reintentar
|
||||
await Task.Delay(_retryDelay);
|
||||
}
|
||||
catch (HttpRequestException) when (attempts <= _maxRetries)
|
||||
{
|
||||
// Error red: reintentar
|
||||
await Task.Delay(_retryDelay);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
@@ -252,24 +274,24 @@ public class ApiClient : IDisposable
|
||||
|
||||
public async Task<string> GetAsync(string url)
|
||||
{
|
||||
return await SendWithRetriesAsync(() => _httpClient.GetAsync(url));
|
||||
return await SendWithRetriesAsync(() => new HttpRequestMessage(HttpMethod.Get, url));
|
||||
}
|
||||
|
||||
public async Task<string> PostJsonAsync(string url, string jsonContent)
|
||||
{
|
||||
using var content = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");
|
||||
return await SendWithRetriesAsync(() => _httpClient.PostAsync(url, content));
|
||||
return await SendWithRetriesAsync(() => new HttpRequestMessage(HttpMethod.Post, url) { Content = content });
|
||||
}
|
||||
|
||||
public async Task<string> PutJsonAsync(string url, string jsonContent)
|
||||
{
|
||||
using var content = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");
|
||||
return await SendWithRetriesAsync(() => _httpClient.PutAsync(url, content));
|
||||
return await SendWithRetriesAsync(() => new HttpRequestMessage(HttpMethod.Put, url) { Content = content });
|
||||
}
|
||||
|
||||
public async Task<string> DeleteAsync(string url)
|
||||
{
|
||||
return await SendWithRetriesAsync(() => _httpClient.DeleteAsync(url));
|
||||
return await SendWithRetriesAsync(() => new HttpRequestMessage(HttpMethod.Delete, url));
|
||||
}
|
||||
|
||||
// Método para enviar archivo y JSON juntos en multipart/form-data
|
||||
@@ -290,7 +312,7 @@ public class ApiClient : IDisposable
|
||||
var jsonContent = new StringContent(jsonString, System.Text.Encoding.UTF8, "application/json");
|
||||
form.Add(jsonContent, jsonFieldName);
|
||||
|
||||
return await SendWithRetriesAsync(() => _httpClient.PostAsync(url, form));
|
||||
return await SendWithRetriesAsync(() => new HttpRequestMessage(HttpMethod.Post, url) { Content = form });
|
||||
}
|
||||
|
||||
public async Task<string> PostMultipartAsync(string url, string filePath, string organizacion, string pedimento,
|
||||
@@ -316,7 +338,7 @@ public class ApiClient : IDisposable
|
||||
form.Add(new StringContent(documentType), "document_type");
|
||||
form.Add(new StringContent(fuente), "fuente");
|
||||
|
||||
return await SendWithRetriesAsync(() => _httpClient.PostAsync(url, form));
|
||||
return await SendWithRetriesAsync(() => new HttpRequestMessage(HttpMethod.Post, url) { Content = form });
|
||||
}
|
||||
|
||||
//public async Task<string> PostMultipartZipAsync(string url, string token, byte[] zipBytes, string zipFileName, string fileFieldName = "archivos")
|
||||
@@ -369,14 +391,14 @@ public class ApiClient : IDisposable
|
||||
//form.Add(new StringContent(documentType), "document_type");
|
||||
//form.Add(new StringContent(fuente), "fuente");
|
||||
|
||||
return await SendWithRetriesAsync(() => _httpClient.PostAsync(url, form));
|
||||
return await SendWithRetriesAsync(() => new HttpRequestMessage(HttpMethod.Post, url) { Content = form });
|
||||
}
|
||||
|
||||
// Método existente que acepta string JSON
|
||||
public async Task<string> PostJsonWithoutAuthAsync(string url, string jsonContent)
|
||||
{
|
||||
using var content = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");
|
||||
return await SendWithRetriesAsync(() => _httpClient.PostAsync(url, content), requireAuth: false);
|
||||
return await SendWithRetriesAsync(() => new HttpRequestMessage(HttpMethod.Post, url) { Content = content }, requireAuth: false);
|
||||
}
|
||||
|
||||
// Nueva sobrecarga que acepta cualquier objeto
|
||||
@@ -460,7 +482,7 @@ public class ApiClient : IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_httpClient.Dispose();
|
||||
// No disposing _httpClient because it's a shared singleton
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user