From b9902f484756f2d57d23662dd5848896ba64abc3 Mon Sep 17 00:00:00 2001 From: "Valeriano A.R" Date: Thu, 16 Jul 2020 03:58:15 +0200 Subject: [PATCH] WebServicesUtils: New implementations of generic service calling. --- VAR.HttpServer | 2 +- VAR.Toolbox/Code/WebServicesUtils.cs | 171 ++++++++++++++++++++++ VAR.Toolbox/UI/Tools/FrmTestWebService.cs | 147 +------------------ VAR.Toolbox/VAR.Toolbox.csproj | 1 + 4 files changed, 180 insertions(+), 141 deletions(-) create mode 100644 VAR.Toolbox/Code/WebServicesUtils.cs diff --git a/VAR.HttpServer b/VAR.HttpServer index a6c0b7c..105cec5 160000 --- a/VAR.HttpServer +++ b/VAR.HttpServer @@ -1 +1 @@ -Subproject commit a6c0b7c8a381631819a7f2f3dac190a5fde16398 +Subproject commit 105cec55d4fb8c27799523cddd2eec7a57970e93 diff --git a/VAR.Toolbox/Code/WebServicesUtils.cs b/VAR.Toolbox/Code/WebServicesUtils.cs new file mode 100644 index 0000000..830e203 --- /dev/null +++ b/VAR.Toolbox/Code/WebServicesUtils.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace VAR.Toolbox.Code +{ + public class WebServicesUtils + { + private static readonly CookieContainer _cookieJar = new CookieContainer(); + + public static string CallApi(string urlService, string urlApiMethod, Dictionary prms, object content, CookieContainer cookieJar = null, string stringContent = null, Dictionary customHeaders = null, string verb = "POST", bool disableCertificateValidation = false) + { + if (urlService?.StartsWith("!") == true) + { + urlService = urlService.Substring(1); + disableCertificateValidation = true; + } + + if (cookieJar == null) { cookieJar = _cookieJar; } + try + { + var sbRequestUrl = new StringBuilder(); + sbRequestUrl.Append(urlService); + if (urlService.EndsWith("/") && urlApiMethod.StartsWith("/")) + { + sbRequestUrl.Append(urlApiMethod.Substring(1)); + } + else + { + sbRequestUrl.Append(urlApiMethod); + } + if (prms != null) + { + foreach (KeyValuePair pair in prms) + { + if (pair.Value == null) + { + sbRequestUrl.AppendFormat("&{0}={1}", pair.Key, string.Empty); + } + else + { + sbRequestUrl.AppendFormat("&{0}={1}", pair.Key, HttpServer.HttpUtility.UrlEncode(pair.Value)); + } + } + } + if (sbRequestUrl.Length > 2048) + { + throw new Exception(string.Format("CallApi: Request URL longer than 2048: url: \"{0}\"", sbRequestUrl.ToString())); + } + + var http = (HttpWebRequest)WebRequest.Create(new Uri(sbRequestUrl.ToString())); + +#if UNIFIKAS_COMMONS + if (disableCertificateValidation) + { + http.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return true; }; + } +#else + if (disableCertificateValidation) + { + throw new NotImplementedException("ApiHelper.CallApi: Can't disable certificate validation"); + } +#endif + http.CookieContainer = cookieJar; + http.Accept = "application/json"; + http.ContentType = "application/json; charset=utf-8"; + http.Method = verb; + if (customHeaders != null) + { + foreach (KeyValuePair customHeader in customHeaders) + { + http.Headers[customHeader.Key] = customHeader.Value; + } + } + + if (verb == "POST") + { + string parsedContent = Json.JsonWriter.WriteObject(content); + if (string.IsNullOrEmpty(stringContent) == false) + { + parsedContent = stringContent; + } + UTF8Encoding encoding = new UTF8Encoding(); + byte[] bytes = encoding.GetBytes(parsedContent); + + Task requestStreamTask = http.GetRequestStreamAsync(); + requestStreamTask.Wait(); + Stream requestStream = requestStreamTask.Result; + requestStream.Write(bytes, 0, bytes.Length); + requestStream.Flush(); + } + + Task responseTask = http.GetResponseAsync(); + responseTask.Wait(); + WebResponse response = responseTask.Result; + var stream = response.GetResponseStream(); + var sr = new StreamReader(stream); + return sr.ReadToEnd(); + } + catch (Exception ex) + { + throw ex; + } + } + + public static string CallSoapMethod(string url, string method, Dictionary parms, string namespaceUrl = "http://tempuri.org", ICredentials credentials = null) + { + // Los servicios SOAP se llaman siempre a través de HTTP. + if (url.ToLower().StartsWith("https://")) + { + url = string.Format("http://{0}", url.Substring("https://".Length)); + } + + // Construir petición + var sbData = new StringBuilder(); + sbData.AppendFormat(""); + sbData.AppendFormat(""); + sbData.AppendFormat(""); + sbData.AppendFormat("<{0} xmlns=\"{1}\">", method, namespaceUrl); + foreach (KeyValuePair parm in parms) + { + if (parm.Value != null && !(parm.Value is DBNull)) + { + sbData.AppendFormat("<{0}>{1}", parm.Key, parm.Value); + } + else + { + sbData.AppendFormat("<{0} i:nil=\"true\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" />", parm.Key); + } + } + sbData.AppendFormat("", method); + sbData.AppendFormat(""); + sbData.AppendFormat(""); + Console.WriteLine(sbData.ToString()); + byte[] postData = Encoding.UTF8.GetBytes(sbData.ToString()); + + // Realizar petición + var client = new System.Net.WebClient(); + if (credentials != null) + { + client.Credentials = credentials; + } + client.Headers.Add("Accept", "text/xml"); + client.Headers.Add("Accept-Charset", "UTF-8"); + client.Headers.Add("Content-Type", "text/xml; charset=UTF-8"); + if (namespaceUrl.ToLower().StartsWith("http")) + { + client.Headers.Add("SOAPAction", string.Format("\"{0}/{1}\"", namespaceUrl, method)); + } + else + { + client.Headers.Add("SOAPAction", string.Format("\"{0}:{1}\"", namespaceUrl, method)); + } + byte[] data; + try + { + data = client.UploadData(url, "POST", postData); + } + catch (Exception ex) + { + throw new Exception(string.Format("Failure calling SoapService: URL: {0}", url), ex); + } + string strData = System.Text.Encoding.UTF8.GetString(data); + return strData; + } + + } +} diff --git a/VAR.Toolbox/UI/Tools/FrmTestWebService.cs b/VAR.Toolbox/UI/Tools/FrmTestWebService.cs index cdd7953..9343f9c 100644 --- a/VAR.Toolbox/UI/Tools/FrmTestWebService.cs +++ b/VAR.Toolbox/UI/Tools/FrmTestWebService.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; -using System.IO; -using System.Net; +using System.Linq; using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using System.Xml; +using VAR.Toolbox.Code; +using VAR.Toolbox.Controls; namespace VAR.Toolbox.UI { @@ -27,11 +25,11 @@ namespace VAR.Toolbox.UI string url = txtUrlSoap.Text; string namespaceUrl = txtNamespaceUrlSoap.Text; string method = txtMethodSoap.Text; - Dictionary parms = StringToDictionary(txtParametersSoap.Text); + Dictionary parms = StringToDictionary(txtParametersSoap.Text).ToDictionary(p => p.Key, p => (object)p.Value); - Dictionary result = CallSoapMethod(url, namespaceUrl, method, parms); + string result = WebServicesUtils.CallSoapMethod(url, method, parms, namespaceUrl); - txtResultSoap.Text = DictionaryToString(result); + txtResultSoap.Text = result; } catch (Exception ex) { @@ -54,7 +52,7 @@ namespace VAR.Toolbox.UI Dictionary parms = StringToDictionary(txtParametersRest.Text); string body = txtBodyRest.Text; - string result = CallApi(url, urlApiMethod, parms, body); + string result = WebServicesUtils.CallApi(url, urlApiMethod, parms, null, stringContent: body); txtResultRest.Text = result; } @@ -91,23 +89,6 @@ namespace VAR.Toolbox.UI return dic; } - /// - /// Serializa un diccionario string,string a una cadena. - /// - /// The dic. - /// - /// VAR - public static string DictionaryToString(Dictionary dic) - { - var sb = new StringBuilder(); - foreach (KeyValuePair entrada in dic) - { - string sKey = entrada.Key.Replace(":", "\\:").Replace(",", "\\,"); - string sVal = entrada.Value.Replace(":", "\\:").Replace(",", "\\,"); - sb.AppendFormat("{0}:{1},", sKey, sVal); - } - return sb.ToString(); - } /// /// Parte una cadena usando un caracter, evitando usar las ocurrencias escapadas con '\\' @@ -136,120 +117,6 @@ namespace VAR.Toolbox.UI return strs; } - /// - /// Llama a un metodo SOAP. Esto requiere que el binding del servicio WCF sea de tipo "basicHttpBinding" - /// - /// The URL. - /// The iface. - /// The method. - /// The parms. - /// - /// 12/05/2014 - /// VAR - public static Dictionary CallSoapMethod(string url, string iface, string method, Dictionary parms) - { - // Los servicios SOAP se llaman siempre a traves de HTTP. - if (url.ToLower().StartsWith("https://")) - { - url = string.Format("http://{0}", url.Substring("https://".Length)); - } - - // Construir peticion - var sbData = new StringBuilder(); - sbData.AppendFormat("\n"); - sbData.AppendFormat("\n"); - sbData.AppendFormat("\n"); - sbData.AppendFormat("<{0} xmlns=\"http://tempuri.org/\">\n", method); - foreach (KeyValuePair parm in parms) - { - sbData.AppendFormat("<{0}>{1}\n", parm.Key, parm.Value); - - // FIXME: Accept null values - //sbData.AppendFormat("<{0} i:nil=\"true\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" />\n", parm.Key); - } - sbData.AppendFormat("\n", method); - sbData.AppendFormat("\n"); - sbData.AppendFormat("\n"); - byte[] postData = Encoding.UTF8.GetBytes(sbData.ToString()); - - // Realizar peticion - var client = new System.Net.WebClient(); - client.Headers.Add("Accept", "text/xml"); - client.Headers.Add("Accept-Charset", "UTF-8"); - client.Headers.Add("Content-Type", "text/xml; charset=UTF-8"); - client.Headers.Add("SOAPAction", string.Format("\"{0}/{1}/{2}\"", "http://tempuri.org", iface, method)); - byte[] data; - try - { - data = client.UploadData(url, "POST", postData); - } - catch (Exception ex) - { - throw new Exception(string.Format("Failure calling SoapService: URL: {0}", url), ex); - } - string strData = System.Text.Encoding.UTF8.GetString(data); - var strReader = new StringReader(strData); - var xmlReader = new XmlTextReader(strReader); - - // Parsear resultado - Dictionary resultObject = new Dictionary(); - while (xmlReader.Read()) - { - if (xmlReader.NodeType == XmlNodeType.Element) - { - string name = xmlReader.Name; - if (name.Contains(":")) - { - name = name.Split(':')[1]; - } - resultObject.Add(name, xmlReader.ReadString()); - } - } - return resultObject; - } - - - private static readonly CookieContainer _cookieJar = new CookieContainer(); - - public static string CallApi(string urlService, string urlApiMethod, Dictionary prms, string content) - { - var sbRequestUrl = new StringBuilder(); - sbRequestUrl.Append(urlService); - sbRequestUrl.Append(urlApiMethod); - if (prms != null) - { - foreach (KeyValuePair pair in prms) - { - sbRequestUrl.AppendFormat("&{0}={1}", pair.Key, Uri.EscapeUriString(pair.Value)); - } - } - if (sbRequestUrl.Length > 2048) - { - throw new Exception(string.Format("CallApi: Request URL longer than 2048: url: \"{0}\"", sbRequestUrl.ToString())); - } - - var http = (HttpWebRequest)WebRequest.Create(new Uri(sbRequestUrl.ToString())); - http.CookieContainer = _cookieJar; - http.Accept = "application/json"; - http.ContentType = "application/json; charset=utf-8"; - http.Method = "POST"; - - UTF8Encoding encoding = new UTF8Encoding(); - byte[] bytes = encoding.GetBytes(content); - - Task requestStreamTask = http.GetRequestStreamAsync(); - requestStreamTask.Wait(); - Stream requestStream = requestStreamTask.Result; - requestStream.Write(bytes, 0, bytes.Length); - requestStream.Flush(); - - Task responseTask = http.GetResponseAsync(); - responseTask.Wait(); - WebResponse response = responseTask.Result; - var stream = response.GetResponseStream(); - var sr = new StreamReader(stream); - return sr.ReadToEnd(); - } } } diff --git a/VAR.Toolbox/VAR.Toolbox.csproj b/VAR.Toolbox/VAR.Toolbox.csproj index c2d6cda..e345db6 100644 --- a/VAR.Toolbox/VAR.Toolbox.csproj +++ b/VAR.Toolbox/VAR.Toolbox.csproj @@ -111,6 +111,7 @@ +