feat: se agregan logs, y se hacen cambios en el modulo registrar mediciones

This commit is contained in:
Leonel Toro 2025-07-01 14:00:41 -04:00
parent 5bd9c2a1a6
commit 4b6204d9e7
32 changed files with 648 additions and 625 deletions

View file

@ -1,17 +1,9 @@
using Azure;
using System.Text.Json;
using DAL;
using Microsoft.Extensions.Configuration;
using Shared.DTO;
using Shared.DTO.Integracion_DGA;
using Shared.DTO.VariablesEntorno;
using Shared.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace BLL.Integracion_DGA
{
@ -24,7 +16,8 @@ namespace BLL.Integracion_DGA
private readonly JobsDgaSupFlujRepository _jobsSupFluj;
private readonly FileLoggerHelper _fileLoggerHelper;
public BusinessLogic(IConfiguration configuration, ApiService apiService, JobsDgaRepository jobs, JobsDgaVilosRepository jobsVilos, JobsDgaSupFlujRepository jobsSupFluj) {
public BusinessLogic(IConfiguration configuration, ApiService apiService, JobsDgaRepository jobs, JobsDgaVilosRepository jobsVilos, JobsDgaSupFlujRepository jobsSupFluj)
{
_configuration = configuration;
_apiService = apiService;
_jobs = jobs;

View file

@ -1,24 +1,28 @@
using Microsoft.Extensions.Configuration;
using Shared.DTO;
using DAL;
using DAL;
using DAS;
using Shared.DTO.Envios_DGA;
using Shared.DTO.VariablesEntorno;
using Shared.Helper;
namespace BLL.Recuperacion_DGA
{
public class EnvioDGA
{
private readonly MedicionScadaRepository _dGAMedicionScadaRepository;
private readonly MedicionScadaVilosRepository _dgaMedicionScadaVilosRepository;
private readonly RegistrarMedicion _registrarMedicion;
public EnvioDGA(MedicionScadaRepository dGAMedicionScadaRepository, RegistrarMedicion registrarMedicion)
public EnvioDGA(MedicionScadaRepository dGAMedicionScadaRepository, RegistrarMedicion registrarMedicion, MedicionScadaVilosRepository dgaMedicionScadaVilosRepository)
{
_dGAMedicionScadaRepository = dGAMedicionScadaRepository;
_registrarMedicion = registrarMedicion;
_dgaMedicionScadaVilosRepository = dgaMedicionScadaVilosRepository;
}
public async Task<bool> RegistrarMedicionesAsync()
{
WriteLineAndLog("Iniciando el proceso de recuperación DGA...");
WriteLineAndLog("Obteniendo Mediciones Scada", ConsoleColor.Green);
var mediciones = await _dGAMedicionScadaRepository.ObtenerMedicionesAsync();
foreach (var medicion in mediciones)
@ -27,38 +31,114 @@ namespace BLL.Recuperacion_DGA
{
if (!string.IsNullOrEmpty(medicion.Code))
{
var rutEmpresa = string.Empty;
if (medicion.tipo_empresa == null)
{
continue;
}
if (medicion.tipo_empresa == "AV")
{
rutEmpresa = CredencialDGA.RutAv;
}
if (medicion.tipo_empresa =="EV")
{
rutEmpresa = CredencialDGA.RutEsval;
}
var body = new MedicionSubterraneaRequest
{
Autenticacion = new Autenticacion
{
Password = string.Empty,
RutEmpresa = string.Empty,
RutUsuario = string.Empty
Password = CredencialDGA.Password,
RutEmpresa = rutEmpresa,
RutUsuario = CredencialDGA.RutUsuario
},
MedicionSubterranea = new Medicion
{
Caudal = medicion.Caudal.ToString() ?? "",
FechaMedicion = medicion.DateOrigen?.ToString("yyyy-MM-dd") ?? "",
HoraMedicion = medicion.DateOrigen?.ToString("HH:mm:ss") ?? "",
NivelFreaticoDelPozo = "",
NivelFreaticoDelPozo = medicion.Nivel.ToString() ?? "",
Totalizador = medicion.Totalizador.ToString() ?? "",
}
};
//TODO: Agregar log texto
await _registrarMedicion.EnviarMedicionAsync(medicion.Code, body, medicion.Id);
}
}
catch (Exception)
catch (Exception ex)
{
//TODO: Agregar log texto
throw;
FileLoggerHelper.LogError($"[Error] {ex.Message}.",ex);
WriteLineAndLog($"Error al enviar la medición con ID {medicion.Code}.", ConsoleColor.Red);
}
}
var medicionesVilos = await _dgaMedicionScadaVilosRepository.ObtenerMedicionesVilosAsync();
foreach (var medicionVilos in medicionesVilos)
{
try
{
if (!string.IsNullOrEmpty(medicionVilos.Code))
{
var rutEmpresa = string.Empty;
if (medicionVilos.tipo_empresa.Equals("AV"))
{
rutEmpresa = CredencialDGA.RutAv;
}
else if (medicionVilos.tipo_empresa.Equals("EV"))
{
rutEmpresa = CredencialDGA.RutEsval;
}
var body = new MedicionSubterraneaRequest
{
Autenticacion = new Autenticacion
{
Password = CredencialDGA.Password,
RutEmpresa = rutEmpresa,
RutUsuario = CredencialDGA.RutUsuario
},
MedicionSubterranea = new Medicion
{
Caudal = medicionVilos.Caudal.ToString() ?? "",
FechaMedicion = medicionVilos.DateOrigen?.ToString("yyyy-MM-dd") ?? "",
HoraMedicion = medicionVilos.DateOrigen?.ToString("HH:mm:ss") ?? "",
NivelFreaticoDelPozo = medicionVilos.Nivel.ToString() ?? "",
Totalizador = medicionVilos.Totalizador.ToString() ?? "",
}
};
await _registrarMedicion.EnviarMedicionAsync(medicionVilos.Code, body, medicionVilos.Id);
}
}
catch (Exception ex)
{
FileLoggerHelper.LogError($"[Error] {ex.Message}.", ex);
WriteLineAndLog($"Error al enviar la medición vilos con ID {medicionVilos.Code}.", ConsoleColor.Red);
}
}
return true;
}
static void WriteLineAndLog(string msj, ConsoleColor? color = null)
{
if (color.HasValue && Enum.IsDefined(typeof(ConsoleColor), color.Value))
{
Console.ForegroundColor = (ConsoleColor)color;
Console.WriteLine(msj);
Console.ResetColor();
}
else
{
Console.WriteLine($"{msj}");
}
FileLoggerHelper.LogInformation($"{msj}");
}
}
}

View file

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace DAL
{

View file

@ -1,14 +1,7 @@
using Microsoft.Data.SqlClient;
using Microsoft.Win32;
using Shared.DTO.Integracion_DGA;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using Dapper;
using Microsoft.Extensions.Configuration;
using Microsoft.Data.SqlClient;
using Shared.DTO.Integracion_DGA;
using Shared.DTO.VariablesEntorno;
namespace DAL
@ -84,7 +77,8 @@ namespace DAL
return true; // Éxito
}
}catch (Exception ex)
}
catch (Exception ex)
{
throw new Exception($"Error: {ex.Message}");
}

View file

@ -1,14 +1,8 @@
using Dapper;
using System.Data;
using Dapper;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Shared.DTO.Integracion_DGA;
using Shared.DTO.VariablesEntorno;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DAL
{

View file

@ -1,14 +1,8 @@
using Dapper;
using System.Data;
using Dapper;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Shared.DTO.Integracion_DGA;
using Shared.DTO.VariablesEntorno;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DAL
{

View file

@ -1,11 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using Dapper;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Shared.DTO.Envios_DGA;
using Shared.DTO.VariablesEntorno;

View file

@ -1,9 +1,8 @@
using Dapper;
using System.Data;
using Dapper;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Shared.DTO.Envios_DGA;
using Shared.DTO.VariablesEntorno;
using System.Data;
namespace DAL
{

View file

@ -0,0 +1,22 @@
using System.Data;
using Dapper;
using Microsoft.Data.SqlClient;
using Shared.DTO.Envios_DGA;
using Shared.DTO.VariablesEntorno;
namespace DAL
{
public class MedicionScadaVilosRepository
{
public async Task<List<MedicionScada>> ObtenerMedicionesVilosAsync()
{
await using var connection = new SqlConnection(BdConexion.StringConnection);
var result = await connection.QueryAsync<MedicionScada>(
"SP_OBTENER_MEDICION_SMARTSCADA_OPERACION_VILOS",
commandType: CommandType.StoredProcedure);
return result.ToList();
}
}
}

View file

@ -45,7 +45,8 @@ namespace BLL.Integracion_DGA
Console.WriteLine($"Error en la solicitud: {response.StatusCode}");
throw new HttpRequestException($"Error en la solicitud HTTP. Código de estado: {response.StatusCode}");
}
}catch (Exception ex)
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
throw new Exception($"Error en la solicitud HTTP: {ex.Message}");

View file

@ -1,9 +1,8 @@
using DAL;
using Microsoft.Extensions.Configuration;
using System.Text;
using System.Text.Json;
using DAL;
using Shared.DTO.Envios_DGA;
using Shared.DTO.VariablesEntorno;
using System.Text;
using System.Text.Json;
namespace DAS
{
@ -20,10 +19,6 @@ namespace DAS
public async Task<bool> EnviarMedicionAsync(string codigoObra, MedicionSubterraneaRequest request, long idMedicion)
{
request.Autenticacion.Password = CredencialDGA.Password;
request.Autenticacion.RutEmpresa = CredencialDGA.RutEmpresa; //TODO: condicionar rut empresa
request.Autenticacion.RutUsuario = CredencialDGA.RutUsuario;
var timeStamp = DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss-0000");
var json = JsonSerializer.Serialize(request);
@ -32,7 +27,7 @@ namespace DAS
content.Headers.Add("codigoObra", codigoObra);
content.Headers.Add("timeStampOrigen", timeStamp);
var response = await _httpClient.PostAsync($"{SubterraneaApiUrl.BaseUrl}{SubterraneaApiUrl.EndPoint}", content);
/*var response = await _httpClient.PostAsync($"{SubterraneaApiUrl.BaseUrl}{SubterraneaApiUrl.EndPoint}", content);
string jsonRecibido = await response.Content.ReadAsStringAsync();
string estado = response.IsSuccessStatusCode ? "OK" : "ERROR";
string comprobante = string.Empty;
@ -62,10 +57,10 @@ namespace DAS
FechaEnvio = DateTime.UtcNow,
IdMedicionSmartscadaOperacion = idMedicion
};
*/
//await _logMedicionScadaRepository.InsertarLogMedicionScadaAsync(logMedicionScada);
await _logMedicionScadaRepository.InsertarLogMedicionScadaAsync(logMedicionScada);
return response.IsSuccessStatusCode;
return true;
}
}
}

View file

@ -1,10 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using BLL.Integracion_DGA;
using BLL.Recuperacion_DGA;
using DAL;
using DAS;
using BLL.Recuperacion_DGA;
using BLL.Integracion_DGA;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Shared.Helper;
using Shared.Utils;
namespace Integracion_DGA
@ -13,10 +14,23 @@ namespace Integracion_DGA
{
static async Task Main(string[] args)
{
try
{
Console.Write("Obteniendo variables de entorno...");
ObtenerVariablesEntorno.AmbientarApiUrlNexus("NEXUS_API_URL");
ObtenerVariablesEntorno.AmbientarUrlApiSubterranea("SUBTERRANEAS_API_URL");
ObtenerVariablesEntorno.AmbientarConexionBd("CONEXION_BD_ENVIO_DGA");
ObtenerVariablesEntorno.AmbientarCredencialesDGA("DGA_CREDENCIALES");
ObtenerVariablesEntorno.ValidarVariablesEntorno();
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"[Error] {ex.Message}");
Console.ResetColor();
FileLoggerHelper.LogInformation($"{ex.Message}");
return;
}
using IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
@ -27,7 +41,6 @@ namespace Integracion_DGA
services.AddScoped<MedicionScadaRepository>();
services.AddScoped<EnvioDGA>();
services.AddHttpClient<RegistrarMedicion>();
//Estos dos servicios son los que migre del otro proyecto
services.AddScoped<JobsDgaRepository>();
services.AddScoped<JobsDgaVilosRepository>();
services.AddScoped<JobsDgaSupFlujRepository>();
@ -37,8 +50,6 @@ namespace Integracion_DGA
})
.Build();
//TODO: Controlar si las variables de ambiente existen
var envioDGA = host.Services.GetRequiredService<EnvioDGA>();
var bussinessLogic = host.Services.GetRequiredService<BusinessLogic>();
var apiService = host.Services.GetRequiredService<ApiService>();

View file

@ -5,6 +5,7 @@ using DAS;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Shared.Helper;
using Shared.Utils;
namespace Recuperacion_DGA
@ -13,10 +14,23 @@ namespace Recuperacion_DGA
{
static async Task Main(string[] args)
{
try
{
Console.WriteLine("Obteniendo variables de entorno...");
ObtenerVariablesEntorno.AmbientarApiUrlNexus("NEXUS_API_URL");
ObtenerVariablesEntorno.AmbientarUrlApiSubterranea("SUBTERRANEAS_API_URL");
ObtenerVariablesEntorno.AmbientarConexionBd("CONEXION_BD_ENVIO_DGA");
ObtenerVariablesEntorno.AmbientarCredencialesDGA("DGA_CREDENCIALES");
ObtenerVariablesEntorno.ValidarVariablesEntorno();
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"[Error] {ex.Message}");
Console.ResetColor();
FileLoggerHelper.LogInformation($"{ex.Message}");
return;
}
using IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
@ -25,25 +39,17 @@ namespace Recuperacion_DGA
services.AddSingleton<IConfiguration>(configuration);
services.AddScoped<MedicionScadaRepository>();
services.AddScoped<MedicionScadaVilosRepository>();
services.AddScoped<EnvioDGA>();
services.AddHttpClient<RegistrarMedicion>();
//Estos dos servicios son los que migre del otro proyecto
services.AddScoped<JobsDgaRepository>();
services.AddScoped<JobsDgaVilosRepository>();
services.AddScoped<JobsDgaSupFlujRepository>();
services.AddScoped<LogMedicionScadaRepository>();
services.AddScoped<ApiService>();
services.AddScoped<BusinessLogic>();
})
.Build();
//TODO: Controlar si las variables de ambiente existen
//TODO: Log de texto
var envioDGA = host.Services.GetRequiredService<EnvioDGA>();
await envioDGA.RegistrarMedicionesAsync();
//TODO: Log de texto
}
}
}

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.Envios_DGA
namespace Shared.DTO.Envios_DGA
{
public class LogMedicionScada
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.Envios_DGA
namespace Shared.DTO.Envios_DGA
{
public class MedicionScada
{
@ -27,6 +21,6 @@ namespace Shared.DTO.Envios_DGA
public decimal? Nivel { get; set; }
public string? TipoEmpresa { get; set; }
public string? tipo_empresa { get; set; }
}
}

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.Envios_DGA
namespace Shared.DTO.Envios_DGA
{
public class MedicionSubterraneaRequest
{
@ -26,5 +20,7 @@ namespace Shared.DTO.Envios_DGA
public string HoraMedicion { get; set; }
public string NivelFreaticoDelPozo { get; set; }
public string Totalizador { get; set; }
public string? TipoEmpresa { get; set; }
}
}

View file

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Shared.DTO.Integracion_DGA;
namespace Shared.DTO.Integracion_DGA;
public partial class DgaMacroResultado
{

View file

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
namespace Shared.DTO.Integracion_DGA;
namespace Shared.DTO.Integracion_DGA;
public partial class DgaMacroResultadoSupFluj
{

View file

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
namespace Shared.DTO.Integracion_DGA;
namespace Shared.DTO.Integracion_DGA;
public partial class DgaMacroResultadoSupFlujSuma
{

View file

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
namespace Shared.DTO.Integracion_DGA;
namespace Shared.DTO.Integracion_DGA;
public partial class DgaMacroResultadoVilos
{

View file

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
namespace Shared.DTO.Integracion_DGA;
namespace Shared.DTO.Integracion_DGA;
public partial class DgaSensorResultado
{

View file

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
namespace Shared.DTO.Integracion_DGA;
namespace Shared.DTO.Integracion_DGA;
public partial class DgaSensorResultadoVilos
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.Integracion_DGA
namespace Shared.DTO.Integracion_DGA
{
public class DocumentResponse
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.Integracion_DGA
namespace Shared.DTO.Integracion_DGA
{
public class HistoricRequest
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.Integracion_DGA
namespace Shared.DTO.Integracion_DGA
{
public class HistoricResponse
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.Integracion_DGA
namespace Shared.DTO.Integracion_DGA
{
public class TagviewsResponse
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.VariablesEntorno
namespace Shared.DTO.VariablesEntorno
{
public static class BdConexion
{

View file

@ -1,14 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.VariablesEntorno
namespace Shared.DTO.VariablesEntorno
{
public static class CredencialDGA
{
public static string RutEmpresa { get; set; } = string.Empty;
public static string RutEsval { get; set; } = string.Empty;
public static string RutAv { get; set; } = string.Empty;
public static string RutUsuario { get; set; } = string.Empty;
public static string Password { get; set; } = string.Empty;
}

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.VariablesEntorno
namespace Shared.DTO.VariablesEntorno
{
public static class NexusApiUrl
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO.VariablesEntorno
namespace Shared.DTO.VariablesEntorno
{
public static class SubterraneaApiUrl
{

View file

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Shared.DTO.VariablesEntorno;
using Shared.DTO.VariablesEntorno;
namespace Shared.Utils
{
@ -34,8 +29,11 @@ namespace Shared.Utils
{
var dictEnv = GetVarEnviromentDict(env);
dictEnv.TryGetValue("RUTEMPRESA", out string? rutEmpresa);
CredencialDGA.RutEmpresa = rutEmpresa ?? string.Empty;
dictEnv.TryGetValue("RUTESVAL", out string? rutEsval);
CredencialDGA.RutEsval = rutEsval ?? string.Empty;
dictEnv.TryGetValue("RUTAV", out string? rutAv);
CredencialDGA.RutAv = rutAv ?? string.Empty;
dictEnv.TryGetValue("RUTUSUARIO", out string? rutUsuario);
CredencialDGA.RutUsuario = rutUsuario ?? string.Empty;
@ -79,5 +77,33 @@ namespace Shared.Utils
dictEnv.TryGetValue("ENDPOINT", out string? endpoint);
SubterraneaApiUrl.EndPoint = endpoint ?? string.Empty;
}
public static void ValidarVariablesEntorno()
{
if (string.IsNullOrWhiteSpace(CredencialDGA.RutEsval))
throw new Exception("La propiedad CredencialDGA.RutEsval está vacía o nula.");
if (string.IsNullOrWhiteSpace(CredencialDGA.RutAv))
throw new Exception("La propiedad CredencialDGA.RutAv está vacía o nula.");
if (string.IsNullOrWhiteSpace(CredencialDGA.RutUsuario))
throw new Exception("La propiedad CredencialDGA.RutUsuario está vacía o nula.");
if (string.IsNullOrWhiteSpace(CredencialDGA.Password))
throw new Exception("La propiedad CredencialDGA.Password está vacía o nula.");
if (string.IsNullOrWhiteSpace(NexusApiUrl.ApiUrl))
throw new Exception("La propiedad NexusApiUrl.ApiUrl está vacía o nula.");
if (string.IsNullOrWhiteSpace(NexusApiUrl.ApiKey))
throw new Exception("La propiedad NexusApiUrl.ApiKey está vacía o nula.");
if (string.IsNullOrWhiteSpace(NexusApiUrl.Version))
throw new Exception("La propiedad NexusApiUrl.Version está vacía o nula.");
if (string.IsNullOrWhiteSpace(NexusApiUrl.DataSource))
throw new Exception("La propiedad NexusApiUrl.DataSource está vacía o nula.");
if (string.IsNullOrWhiteSpace(NexusApiUrl.Resolution))
throw new Exception("La propiedad NexusApiUrl.Resolution está vacía o nula.");
if (string.IsNullOrWhiteSpace(BdConexion.StringConnection))
throw new Exception("La propiedad BdConexion.StringConnection está vacía o nula.");
if (string.IsNullOrWhiteSpace(SubterraneaApiUrl.BaseUrl))
throw new Exception("La propiedad SubterraneaApiUrl.BaseUrl está vacía o nula.");
if (string.IsNullOrWhiteSpace(SubterraneaApiUrl.EndPoint))
throw new Exception("La propiedad SubterraneaApiUrl.EndPoint está vacía o nula.");
}
}
}