581 lines
29 KiB
C#
581 lines
29 KiB
C#
using Microsoft.Extensions.Configuration;
|
|
using Net.Business.Entities.ServicesLayer;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Net.Security;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Net.Connection.ServiceLayer
|
|
{
|
|
public class ConnectionServiceLayer
|
|
{
|
|
public static bool ServicioActivo = false;
|
|
public static string SLSession;
|
|
|
|
// Se invoca solo cuando SAP rechaza un envio: (ruta del recurso, JSON enviado, respuesta de SAP).
|
|
// Lo asigna Startup (esta capa no conoce HANA).
|
|
public static Action<string, object, string> ErrorLogger;
|
|
|
|
private static void LogErrorEnvio(string query, object jsonEnviado, string respuesta)
|
|
{
|
|
try { ErrorLogger?.Invoke(query, jsonEnviado, respuesta); }
|
|
catch { /* el log nunca debe romper el flujo principal */ }
|
|
}
|
|
|
|
private readonly string _url;
|
|
private readonly string _company;
|
|
private readonly string _user;
|
|
private readonly string _password;
|
|
private readonly string _language;
|
|
private readonly IHttpClientFactory _httpClient;
|
|
private ResponseLoginServiceLayer _responseLoginServiceLayer;
|
|
|
|
public ConnectionServiceLayer(IConfiguration configuration, IHttpClientFactory clientFactory)
|
|
{
|
|
_url = configuration["SapServiceLayer:url"];
|
|
_company = configuration["SapServiceLayer:company"];
|
|
_user = configuration["SapServiceLayer:user"];
|
|
_password = configuration["SapServiceLayer:password"];
|
|
_language = configuration["SapServiceLayer:language"];
|
|
_httpClient = clientFactory;
|
|
_responseLoginServiceLayer = new ResponseLoginServiceLayer();
|
|
}
|
|
|
|
// Inicia sesion en el Service Layer (cookie B1SESSION). Usa SapServiceLayer:company/user/password de appsettings.json
|
|
public async Task<ResponseLoginServiceLayer> Login()
|
|
{
|
|
try
|
|
{
|
|
// CONSTRUIMOS LA URL DE LA ACCIÓN
|
|
var urlBuilder_ = new StringBuilder();
|
|
urlBuilder_.Append(_url != null ? _url.TrimEnd('/') : "")
|
|
.Append("/Login");
|
|
var url_ = urlBuilder_.ToString();
|
|
|
|
// RECUPERAMOS EL HttpClient
|
|
|
|
var client_ = _httpClient.CreateClient("bypass-ssl-validation");
|
|
|
|
|
|
using (var request_ = new HttpRequestMessage())
|
|
{
|
|
///////////////////////////////////////
|
|
// CONSTRUIMOS LA PETICIÓN (REQUEST) //
|
|
///////////////////////////////////////
|
|
// DEFINIMOS EL Content CON EL OBJETO A ENVIAR SERIALIZADO.
|
|
request_.Content = new StringContent("{\"CompanyDB\":\"" + _company + "\",\"Password\":\"" + _password + "\",\"UserName\":\"" + _user + "\"}");
|
|
|
|
// DEFINIMOS EL ContentType, EN ESTE CASO ES "application/json"
|
|
request_.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
|
|
request_.Headers.Add("cache-control", "no-cache");
|
|
|
|
// DEFINIMOS EL MÉTODO HTTP
|
|
request_.Method = new HttpMethod("POST");
|
|
|
|
// DEFINIMOS LA URI
|
|
request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);
|
|
|
|
// DEFINIMOS EL Accept, EN ESTE CASO ES "application/json"
|
|
request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
|
|
|
/////////////////////////////////////////
|
|
// CONSTRUIMOS LA RESPUESTA (RESPONSE) //
|
|
/////////////////////////////////////////
|
|
// Utilizamos ConfigureAwait(false) para evitar el DeadLock.
|
|
var response_ = await client_.SendAsync(request_).ConfigureAwait(false);
|
|
|
|
// OBTENEMOS EL Content DEL RESPONSE como un String
|
|
// Utilizamos ConfigureAwait(false) para evitar el DeadLock.
|
|
var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
|
|
|
// SI ES LA RESPUESTA ESPERADA !! ...
|
|
if (response_.StatusCode == System.Net.HttpStatusCode.OK) // 200
|
|
{
|
|
// DESERIALIZAMOS Content DEL RESPONSE
|
|
_responseLoginServiceLayer = JsonConvert.DeserializeObject<ResponseLoginServiceLayer>(responseText_);
|
|
_responseLoginServiceLayer.ServicioActivo = true;
|
|
_responseLoginServiceLayer.MensajeLogin = "Autenticación Correcta";
|
|
return _responseLoginServiceLayer;
|
|
}
|
|
else
|
|
// SI NO SE ESTÁ AUTORIZADO ...
|
|
if (response_.StatusCode == System.Net.HttpStatusCode.Unauthorized) // 401
|
|
{
|
|
_responseLoginServiceLayer = JsonConvert.DeserializeObject<ResponseLoginServiceLayer>(responseText_);
|
|
_responseLoginServiceLayer.ServicioActivo = false;
|
|
_responseLoginServiceLayer.MensajeLogin = "401 Unauthorized. Las credenciales de acceso del usuario son incorrectas.";
|
|
return _responseLoginServiceLayer;
|
|
}
|
|
else
|
|
// CUALQUIER OTRA RESPUESTA ...
|
|
if (response_.StatusCode != System.Net.HttpStatusCode.OK && // 200
|
|
response_.StatusCode != System.Net.HttpStatusCode.NoContent) // 204
|
|
{
|
|
_responseLoginServiceLayer = JsonConvert.DeserializeObject<ResponseLoginServiceLayer>(responseText_);
|
|
_responseLoginServiceLayer.ServicioActivo = false;
|
|
_responseLoginServiceLayer.MensajeLogin = "401 Unauthorized. Las credenciales de acceso del usuario son incorrectas.";
|
|
return _responseLoginServiceLayer;
|
|
}
|
|
|
|
// RETORNAMOS EL OBJETO POR DEFECTO ESPERADO
|
|
return _responseLoginServiceLayer;
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_responseLoginServiceLayer.ServicioActivo = false;
|
|
_responseLoginServiceLayer.MensajeLogin = ex.Message.ToString();
|
|
return _responseLoginServiceLayer;
|
|
}
|
|
}
|
|
// GET al Service Layer. dinamico = true: la respuesta es una sola entidad (ej. Invoices(123)); false: coleccion { value: [...] }
|
|
public async Task<List<T>> GetAsync<T>(string Query, int maxpagesize,bool dinamico = false)
|
|
{
|
|
try
|
|
{
|
|
// CONSTRUIMOS LA URL DE LA ACCIÓN
|
|
var urlBuilder_ = new StringBuilder();
|
|
urlBuilder_.Append(_url != null ? _url.TrimEnd('/') : "")
|
|
.Append("/" + Query);
|
|
var url_ = urlBuilder_.ToString();
|
|
|
|
// RECUPERAMOS EL HttpClient
|
|
var client_ = _httpClient.CreateClient("bypass-ssl-validation");
|
|
|
|
//AUTENTICAMOS PARA REALIZAR LAS CONSULTAS
|
|
await Login();
|
|
|
|
using (var request_ = new HttpRequestMessage())
|
|
{
|
|
///////////////////////////////////////
|
|
// CONSTRUIMOS LA PETICIÓN (REQUEST) //
|
|
///////////////////////////////////////
|
|
// DEFINIMOS EL MÉTODO HTTP
|
|
request_.Method = new HttpMethod("GET");
|
|
|
|
// DEFINIMOS LA URI
|
|
request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);
|
|
|
|
// DEFINIMOS EL Accept, EN ESTE CASO ES "application/json"
|
|
request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
|
request_.Headers.Add("cache-control", "no-cache");
|
|
request_.Headers.Add("Prefer", "odata.maxpagesize=" + maxpagesize.ToString());
|
|
|
|
|
|
// ASIGNAMOS A LA CABECERA DE LA PETICIÓN EL TOKEN JWT.
|
|
if (_responseLoginServiceLayer.ServicioActivo)
|
|
request_.Headers.Add("Cookie", "B1SESSION=" + _responseLoginServiceLayer.SessionId);
|
|
/////////////////////////////////////////
|
|
// CONSTRUIMOS LA RESPUESTA (RESPONSE) //
|
|
/////////////////////////////////////////
|
|
// Utilizamos ConfigureAwait(false) para evitar el DeadLock.
|
|
var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
|
|
|
|
// OBTENEMOS EL Content DEL RESPONSE como un String
|
|
// Utilizamos ConfigureAwait(false) para evitar el DeadLock.
|
|
var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
|
|
|
// SI ES LA RESPUESTA ESPERADA !! ...
|
|
if (response_.StatusCode == System.Net.HttpStatusCode.OK) // 200
|
|
{
|
|
// DESERIALIZAMOS Content DEL RESPONSE
|
|
if (!dinamico)
|
|
{
|
|
var responseBody_ = JsonConvert.DeserializeObject<ResponseGetServiceLayer<T>>(responseText_);
|
|
return responseBody_.value;
|
|
}
|
|
|
|
if (dinamico)
|
|
{
|
|
List<T> lista = new List<T>();
|
|
dynamic responseBody = JsonConvert.DeserializeObject<T>(responseText_);
|
|
lista.Add(responseBody);
|
|
return lista;
|
|
}
|
|
|
|
}
|
|
|
|
// RETORNAMOS EL OBJETO POR DEFECTO ESPERADO
|
|
return default(List<T>);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
// NO UTILIZAMOS CATCH,
|
|
// PASAMOS LA EXCEPCIÓN A LA APP.
|
|
}
|
|
}
|
|
// POST con cuerpo JSON. Crea un documento en SAP. Si SAP rechaza, devuelve Exito = false y guarda el JSON enviado
|
|
// con ErrorLogger (tabla ITCA_LOG_INTEGRACION)
|
|
public Task<T> PostAsync<T>(string Query, object obj)
|
|
{
|
|
return EnviarPostAsync<T>(Query, obj, true, false);
|
|
}
|
|
|
|
// POST sin cuerpo para reabrir un documento (ej. Invoices(n)/Reopen). SAP responde 204 sin contenido y se toma como exito
|
|
public Task<T> PostReOpen<T>(string Query)
|
|
{
|
|
return EnviarPostAsync<T>(Query, null, false, true);
|
|
}
|
|
|
|
// POST sin cuerpo para cerrar un documento (.../Close). SAP responde 204 sin contenido y se toma como exito
|
|
public Task<T> PostClose<T>(string Query)
|
|
{
|
|
return EnviarPostAsync<T>(Query, null, false, true);
|
|
}
|
|
|
|
// Nucleo comun de los envios POST al Service Layer (PostAsync, PostReOpen, PostClose). Reintenta una vez si la sesion
|
|
// expiro (401). conCuerpo: envia obj como JSON y, si SAP rechaza, guarda el JSON enviado con ErrorLogger.
|
|
// aceptaSinContenido: toma el 204 (sin cuerpo) como exito.
|
|
private async Task<T> EnviarPostAsync<T>(string Query, object obj, bool conCuerpo, bool aceptaSinContenido)
|
|
{
|
|
|
|
try
|
|
{
|
|
// CONSTRUIMOS LA URL DE LA ACCIÓN
|
|
var urlBuilder_ = new StringBuilder();
|
|
urlBuilder_.Append(_url != null ? _url.TrimEnd('/') : "")
|
|
.Append("/" + Query);
|
|
var url_ = urlBuilder_.ToString();
|
|
|
|
// RECUPERAMOS EL HttpClient
|
|
var client_ = _httpClient.CreateClient("bypass-ssl-validation");
|
|
|
|
int NumError = 0;
|
|
|
|
band:
|
|
|
|
using (var request_ = new HttpRequestMessage())
|
|
{
|
|
///////////////////////////////////////
|
|
// CONSTRUIMOS LA PETICIÓN (REQUEST) //
|
|
///////////////////////////////////////
|
|
// DEFINIMOS EL MÉTODO HTTP GET
|
|
request_.Method = new HttpMethod("POST");
|
|
|
|
// DEFINIMOS LA URI
|
|
request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);
|
|
|
|
// DEFINIMOS EL Accept, EN ESTE CASO ES "application/json"
|
|
request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
|
if (conCuerpo)
|
|
request_.Content = new StringContent(JsonConvert.SerializeObject(obj), System.Text.Encoding.UTF8, "application/json");
|
|
|
|
// ASIGNAMOS A LA CABECERA DE LA PETICIÓN EL TOKEN JWT.
|
|
if (_responseLoginServiceLayer.ServicioActivo)
|
|
request_.Headers.Add("Cookie", "B1SESSION=" + _responseLoginServiceLayer.SessionId);
|
|
|
|
/////////////////////////////////////////
|
|
// CONSTRUIMOS LA RESPUESTA (RESPONSE) //
|
|
/////////////////////////////////////////
|
|
// Utilizamos ConfigureAwait(false) para evitar el DeadLock.
|
|
var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
|
|
|
|
// OBTENEMOS EL Content DEL RESPONSE como un String
|
|
// Utilizamos ConfigureAwait(false) para evitar el DeadLock.
|
|
var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
|
|
|
// SI ES LA RESPUESTA ESPERADA !! ...
|
|
if (response_.StatusCode == System.Net.HttpStatusCode.OK || response_.StatusCode == System.Net.HttpStatusCode.Created || (aceptaSinContenido && response_.StatusCode == System.Net.HttpStatusCode.NoContent)) // 200, Created o 204
|
|
{
|
|
// DESERIALIZAMOS Content DEL RESPONSE
|
|
// Un 204 (Reopen/Close) viene sin cuerpo: Deserialize devolveria null, asi que se crea una instancia vacia
|
|
dynamic responseBody = (aceptaSinContenido && string.IsNullOrWhiteSpace(responseText_))
|
|
? Activator.CreateInstance<T>()
|
|
: JsonConvert.DeserializeObject<T>(responseText_);
|
|
responseBody.Exito = true;
|
|
var estado = (int)response_.StatusCode;
|
|
responseBody.CodigoHttp = estado.ToString();
|
|
responseBody.Mensaje = "SE ENVIO CORRECTAMENTE A SAP BO ";
|
|
return responseBody;
|
|
}
|
|
else
|
|
// SI NO SE ESTÁ AUTORIZADO ...
|
|
if (response_.StatusCode == System.Net.HttpStatusCode.Unauthorized) // 401
|
|
{
|
|
|
|
NumError += 1;
|
|
|
|
_responseLoginServiceLayer = JsonConvert.DeserializeObject<ResponseLoginServiceLayer>(responseText_);
|
|
_responseLoginServiceLayer.ServicioActivo = false;
|
|
|
|
if (NumError == 2)
|
|
{
|
|
dynamic responseBody = JsonConvert.DeserializeObject<T>(responseText_);
|
|
responseBody.Exito = false;
|
|
var estado = (int)response_.StatusCode;
|
|
responseBody.CodigoHttp = estado.ToString();
|
|
responseBody.Mensaje = "Services Unauthorized : " + _responseLoginServiceLayer.error.message.ToString();
|
|
if (conCuerpo) LogErrorEnvio(Query, obj, responseBody.Mensaje);
|
|
return responseBody;
|
|
}
|
|
|
|
|
|
if (_responseLoginServiceLayer.error.code.ToString() == "301")
|
|
{
|
|
await Login();
|
|
}
|
|
|
|
goto band;
|
|
}
|
|
else
|
|
// CUALQUIER OTRA RESPUESTA ...
|
|
if (response_.StatusCode != System.Net.HttpStatusCode.OK && // 200
|
|
response_.StatusCode != System.Net.HttpStatusCode.NoContent) // 204
|
|
{
|
|
|
|
NumError += 1;
|
|
|
|
_responseLoginServiceLayer = JsonConvert.DeserializeObject<ResponseLoginServiceLayer>(responseText_);
|
|
_responseLoginServiceLayer.ServicioActivo = false;
|
|
|
|
if (NumError == 2)
|
|
{
|
|
dynamic responseBody = JsonConvert.DeserializeObject<T>(responseText_);
|
|
responseBody.Exito = false;
|
|
var estado = (int)response_.StatusCode;
|
|
responseBody.CodigoHttp = estado.ToString();
|
|
responseBody.Mensaje = "Error Services : " + _responseLoginServiceLayer.error.message.ToString();
|
|
if (conCuerpo) LogErrorEnvio(Query, obj, responseBody.Mensaje);
|
|
return responseBody;
|
|
}
|
|
|
|
if (_responseLoginServiceLayer.error.code.ToString() == "301")
|
|
{
|
|
await Login();
|
|
}
|
|
|
|
goto band;
|
|
}
|
|
|
|
// RETORNAMOS EL OBJETO POR DEFECTO ESPERADO
|
|
return default(T);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
// NO UTILIZAMOS CATCH,
|
|
// PASAMOS LA EXCEPCIÓN A LA APP.
|
|
}
|
|
}
|
|
// PATCH con cuerpo JSON. OJO: con un 204 real devuelve null sin marcar exito (bug conocido); para PATCH sin respuesta usar PatchNoContentAsync
|
|
public async Task<T> PatchAsyncSBA<T>(string Query, object obj)
|
|
{
|
|
try
|
|
{
|
|
// CONSTRUIMOS LA URL DE LA ACCIÓN
|
|
var urlBuilder_ = new StringBuilder();
|
|
urlBuilder_.Append(_url != null ? _url.TrimEnd('/') : "")
|
|
.Append("/" + Query);
|
|
var url_ = urlBuilder_.ToString();
|
|
|
|
// RECUPERAMOS EL HttpClient
|
|
var client_ = _httpClient.CreateClient("bypass-ssl-validation");
|
|
|
|
int NumError = 0;
|
|
|
|
band:
|
|
|
|
using (var request_ = new HttpRequestMessage())
|
|
{
|
|
///////////////////////////////////////
|
|
// CONSTRUIMOS LA PETICIÓN (REQUEST) //
|
|
///////////////////////////////////////
|
|
// DEFINIMOS EL MÉTODO HTTP GET
|
|
request_.Method = new HttpMethod("PATCH");
|
|
|
|
// DEFINIMOS LA URI
|
|
request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);
|
|
|
|
// DEFINIMOS EL Accept, EN ESTE CASO ES "application/json"
|
|
request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
|
request_.Content = new StringContent(JsonConvert.SerializeObject(obj), System.Text.Encoding.UTF8, "application/json");
|
|
|
|
// ASIGNAMOS A LA CABECERA DE LA PETICIÓN EL TOKEN JWT.
|
|
if (_responseLoginServiceLayer.ServicioActivo)
|
|
request_.Headers.Add("Cookie", "B1SESSION=" + _responseLoginServiceLayer.SessionId);
|
|
|
|
/////////////////////////////////////////
|
|
// CONSTRUIMOS LA RESPUESTA (RESPONSE) //
|
|
/////////////////////////////////////////
|
|
// Utilizamos ConfigureAwait(false) para evitar el DeadLock.
|
|
var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
|
|
|
|
// OBTENEMOS EL Content DEL RESPONSE como un String
|
|
// Utilizamos ConfigureAwait(false) para evitar el DeadLock.
|
|
var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
|
|
|
// SI ES LA RESPUESTA ESPERADA !! ...
|
|
if (response_.StatusCode == System.Net.HttpStatusCode.OK || response_.StatusCode == System.Net.HttpStatusCode.Created) // 200 or Created
|
|
{
|
|
// DESERIALIZAMOS Content DEL RESPONSE
|
|
dynamic responseBody = JsonConvert.DeserializeObject<T>(responseText_);
|
|
var estado = (int)response_.StatusCode;
|
|
responseBody.Mensaje = "SE ENVIO CORRECTAMENTE A SAP BO ";
|
|
return responseBody;
|
|
}
|
|
else
|
|
// SI NO SE ESTÁ AUTORIZADO ...
|
|
if (response_.StatusCode == System.Net.HttpStatusCode.Unauthorized) // 401
|
|
{
|
|
|
|
NumError += 1;
|
|
|
|
_responseLoginServiceLayer = JsonConvert.DeserializeObject<ResponseLoginServiceLayer>(responseText_);
|
|
_responseLoginServiceLayer.ServicioActivo = false;
|
|
|
|
if (NumError == 2)
|
|
{
|
|
dynamic responseBody = JsonConvert.DeserializeObject<T>(responseText_);
|
|
var estado = (int)response_.StatusCode;
|
|
responseBody.Mensaje = "Services Unauthorized : " + _responseLoginServiceLayer.error.message.ToString();
|
|
LogErrorEnvio(Query, obj, responseBody.Mensaje);
|
|
return responseBody;
|
|
}
|
|
|
|
|
|
if (_responseLoginServiceLayer.error.code.ToString() == "301")
|
|
{
|
|
await Login();
|
|
goto band;
|
|
}
|
|
}
|
|
else
|
|
// CUALQUIER OTRA RESPUESTA ...
|
|
if (response_.StatusCode != System.Net.HttpStatusCode.OK && response_.StatusCode != System.Net.HttpStatusCode.NoContent) // 204
|
|
{
|
|
|
|
//NumError += 1;
|
|
|
|
_responseLoginServiceLayer = JsonConvert.DeserializeObject<ResponseLoginServiceLayer>(responseText_);
|
|
_responseLoginServiceLayer.ServicioActivo = false;
|
|
|
|
dynamic responseBody = JsonConvert.DeserializeObject<T>(responseText_);
|
|
var estado = (int)response_.StatusCode;
|
|
responseBody.Mensaje = "Error Services : " + _responseLoginServiceLayer.error.message.ToString();
|
|
LogErrorEnvio(Query, obj, responseBody.Mensaje);
|
|
return responseBody;
|
|
}
|
|
|
|
// RETORNAMOS EL OBJETO POR DEFECTO ESPERADO
|
|
return default(T);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return default(T);
|
|
}
|
|
}
|
|
|
|
// === NUEVO (SolicitudTransferencia / Picking HojaRuta Cerrar) ===
|
|
//
|
|
// PatchAsyncSBA<T>/PostAsync<T> estan pensados para respuestas con body
|
|
// (200/201) que se deserializan a T y se les "inyecta" Exito/Mensaje/CodigoHttp
|
|
// via dynamic - no sirven para una respuesta sin body como el 204 real que
|
|
// devuelve SAP en un PATCH exitoso o en una accion /Close, y PatchAsyncSBA
|
|
// tiene ademas un bug conocido ahi (ver docs/PORTE_FUNCIONALIDAD_NUEVA.md,
|
|
// hallazgo #2): con un 204 real cae a "return default(T)" sin marcar exito.
|
|
// Por eso estos dos metodos nuevos son deliberadamente simples: no devuelven
|
|
// un T deserializado, solo exito (sin excepcion) o fallo (excepcion con el
|
|
// mensaje real de SAP).
|
|
|
|
public async Task PatchNoContentAsync(string Query, object obj, Dictionary<string, string> extraHeaders = null)
|
|
{
|
|
var urlBuilder_ = new StringBuilder();
|
|
urlBuilder_.Append(_url != null ? _url.TrimEnd('/') : "").Append("/" + Query);
|
|
var url_ = urlBuilder_.ToString();
|
|
|
|
var client_ = _httpClient.CreateClient("bypass-ssl-validation");
|
|
|
|
await Login();
|
|
|
|
using (var request_ = new HttpRequestMessage())
|
|
{
|
|
request_.Method = new HttpMethod("PATCH");
|
|
request_.RequestUri = new Uri(url_, UriKind.RelativeOrAbsolute);
|
|
request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
|
request_.Content = new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json");
|
|
|
|
if (_responseLoginServiceLayer.ServicioActivo)
|
|
request_.Headers.Add("Cookie", "B1SESSION=" + _responseLoginServiceLayer.SessionId);
|
|
|
|
if (extraHeaders != null)
|
|
{
|
|
foreach (var kv in extraHeaders)
|
|
request_.Headers.Add(kv.Key, kv.Value);
|
|
}
|
|
|
|
var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
|
|
var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
|
|
|
if (response_.StatusCode == HttpStatusCode.OK || response_.StatusCode == HttpStatusCode.NoContent)
|
|
{
|
|
return; // exito real - sin body que parsear
|
|
}
|
|
|
|
var mensajeError = ExtraerMensajeErrorSap(responseText_);
|
|
LogErrorEnvio(Query, obj, mensajeError);
|
|
throw new Exception(mensajeError);
|
|
}
|
|
}
|
|
|
|
public async Task PostActionAsync(string Query)
|
|
{
|
|
var urlBuilder_ = new StringBuilder();
|
|
urlBuilder_.Append(_url != null ? _url.TrimEnd('/') : "").Append("/" + Query);
|
|
var url_ = urlBuilder_.ToString();
|
|
|
|
var client_ = _httpClient.CreateClient("bypass-ssl-validation");
|
|
|
|
await Login();
|
|
|
|
using (var request_ = new HttpRequestMessage())
|
|
{
|
|
request_.Method = new HttpMethod("POST");
|
|
request_.RequestUri = new Uri(url_, UriKind.RelativeOrAbsolute);
|
|
request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
|
request_.Content = new StringContent("{}", Encoding.UTF8, "application/json");
|
|
|
|
if (_responseLoginServiceLayer.ServicioActivo)
|
|
request_.Headers.Add("Cookie", "B1SESSION=" + _responseLoginServiceLayer.SessionId);
|
|
|
|
var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
|
|
var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
|
|
|
if (response_.StatusCode == HttpStatusCode.OK || response_.StatusCode == HttpStatusCode.Created || response_.StatusCode == HttpStatusCode.NoContent)
|
|
{
|
|
return; // exito real - sin body que parsear
|
|
}
|
|
|
|
throw new Exception(ExtraerMensajeErrorSap(responseText_));
|
|
}
|
|
}
|
|
|
|
private static string ExtraerMensajeErrorSap(string responseText)
|
|
{
|
|
try
|
|
{
|
|
var parsed = JsonConvert.DeserializeObject<ResponseLoginServiceLayer>(responseText);
|
|
var mensaje = parsed?.error?.message;
|
|
if (mensaje == null) return responseText;
|
|
// "message" esta tipado como object en ErrorServiceLayer (ver
|
|
// ResponseLoginServiceLayer.cs) - Json.NET lo deja como JObject.
|
|
if (mensaje is JObject jMensaje) return jMensaje.Value<string>("value") ?? responseText;
|
|
return mensaje.ToString();
|
|
}
|
|
catch
|
|
{
|
|
return responseText;
|
|
}
|
|
}
|
|
}
|
|
}
|