Mostrando entradas con la etiqueta WEB Services. Mostrar todas las entradas
Mostrando entradas con la etiqueta WEB Services. Mostrar todas las entradas

miércoles, 18 de febrero de 2015

Manipular Ficheros físicos mediante Web Services

No se si alguna vez os ha surgido la necesidad de copiar o mover ficheros desde el cliente por roles o a través de Web Services.
Desde el cliente clásico funciona sin problemas, pero a la hora de hacerlo funcionar por Web Services surge el quebradero de cabeza.
Hay por ahí teorías que dan una posible solución que tiene que ver con que las funciones COPY,EXISTS,ERASE,etc.... no funcionan en la capa de WS.
Pero este no es el problema, el problema es que tenemos tres niveles en tres equipos. Es decir: que en nuestra arquitectura tenemos el cliente del Web Service (Capa 1), El Web Service en el servidor (Capa 2) y el servidor donde están los ficheros (Capa 3).
No se si habréis podido comprobar que si los ficheros a manipular están en el mismo servidor que donde tenemos instalada la capa de Web Service el problema desaparece. es más, es una de las recomendaciones que hace Microsoft para solucionar el problema.


La solución correcta consiste en Delegar servicios. Como ya he comentado, Microsoft recomienda que los archivos estén en el mismo servidor que la capa de Web Service para ahorrarte la enrevesada configuración de la Delegación.

miércoles, 17 de diciembre de 2014

Llamar a Web-Services de Navision desde Navision


PAra consumir los webservices de un servidor de Navision desde otro servidor de Navision tenemos que montar una petición httpRequest pasándole un XML bien formado y recuperar la respuesta para saber que es lo que ha ocurrido en el servidor de destino.

Para ello primero declaramos las variables:
NameDataTypeSubtypeLength
XmlHttpRequest Automation'Microsoft XML, v4.0'.XMLHTTP 
XmlDocAutomation'Microsoft XML, v4.0'.DOMDocument 
XmlStringText 1024
BTSoapBigText  
BTValoresBigText    


Creamos un BigText y le añadimos la cabecera de la petición:

BTPasado.ADDTEXT('<?xml version="1.0" encoding="utf-8"?>');
BTPasado.ADDTEXT('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">');
BTPasado.ADDTEXT('<soap:Body>');
BTPasado.ADDTEXT(STRSUBSTNO('<%1 xmlns="urn:microsoft-dynamics-schemas/codeunit/%2">','MiFuncion','MiCodeUnit'));

BTValores.ADDTEXT('<nombre_parametro_que_espera_MiCodeunit_MiFuncion>');
BTValores.ADDTEXT('MI-VALOR');
BTValores.ADDTEXT('</nombre_parametro_que_espera_MiCodeunit_MiFuncion>');

BTPasado.ADDTEXT(STRSUBSTNO('</%1>','MiFuncion'));

BTPasado.ADDTEXT('</soap:Body>');
BTPasado.ADDTEXT('</soap:Envelope>');


Como veis es bien sencillo montar la petición de nuestro httprequest.
Ahora hacemos la llamada:

NameDataType         Subtype

XmlDocPasado              Automation'Microsoft XML, v4.0'.DOMDocument

IF (ISCLEAR(XmlHttpRequest)) THEN
  CREATE(XmlHttpRequest);

XmlHttpRequest.open('POST','http://servidor:7047/DynamicsNAV/WS/empresa/Codeunit/MiCodeunit',FALSE,'DOMINIO\usuario','password');
XmlHttpRequest.setRequestHeader('Host', 'localhost');
XmlHttpRequest.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
XmlHttpRequest.setRequestHeader('Content-Length', FORMAT(BTPasado.LENGTH));
XmlHttpRequest.setRequestHeader('SOAPAction','MiFuncion');
XmlHttpRequest.send(BTPasado);
XmlDocPasado := XmlHttpRequest.responseXML;


Con esto obtendríamos en XmlDocPasado un XML con el resultado.

jueves, 23 de enero de 2014

Instalar los WEB SERVICES de Navision en un servidor

En este post explicaremos como instalar el servicio de Navision de la capa de Web Services.
Ejecutamos el instalador de la carpeta del CD ServiceTier/Microsoft Dynamics Nav Service.msi
y seguimos los pasos.

Una vez instalado, en los 2 servicios de windows creados poner un usuario y contraseña que tenga permisos y roles en navision. Por lo que ponemos un usuario que sea super.

Hay que tener en cuenta,para los que vais a acceder desde php, que por defecto viene la autenticación NTLM desactivada. Es necesario que este activada para acceder con php.
Para activarla, buscamos el archivo CustomSeting.config que suele estar en
C:\Program Files (x86)\Microsoft Dynamics NAV\60\Service\CustomSeting.config y en la entrada <add key="WebServicesUseNTLMAuthentication" value="false"></add> le ponemos true.

jueves, 26 de diciembre de 2013

Zona Horaria en Navision WEB Service

Trabajando con los campos de tipo time desde los webservices se da el caso que la hora no se graba correctamente. Esto es por la configuracion del archivo CustomSettings.config del servidor de Web Service.
No voy a hacer una entrada detallada porque esta todo perfectamente explicado en este blog. Solamente saber, que para evitarnos quebraderos de cabeza, poner que la hora de los web services es la misma del servidor con la siguiente entrada:
<add key="WebServicesDefaultTimeZone" value="Server Time Zone"></add>

miércoles, 27 de noviembre de 2013

Consumir Web Services de Navision desde Reporting Services Parte 4

Puedes consultar las partes anteriores aquí:
parte 1 y parte 2 y parte 3
Una vez creado el ensamblado pegamos nuestras dlls compiladas (Explicado en post anteriores) en el servidor de SQL.

Entramos en el SQL Server Management Studio y modificamos la propiedad TRUSTWORTHY de la Base de Datos para indicarle que la instancia de SQL confíe en la base de datos y deje ejecutar nuestro ensamblado y no lo interprete como código malicioso:

ALTER DATABASE MI_BASE_DE_DATOS
SET TRUSTWORTHY ON

Ahora creamos nuestro ensamblado en la base de datos con la siguiente instrucción:

CREATE
ASSEMBLY CLRSP
FROM
'C:\CLRSP\CLRSP.dll'
--Dirección de nuestro ensamblado en el servidor
WITH
permission_set = EXTERNAL_ACCESS

Creamos el XML en la base de datos con la siguiente instrucción:
CREATE
ASSEMBLY [XmlSerializers]
FROM
'C:\CLRSP\CLRSP.XmlSerializers.dll'
--Dirección de nuestro ensamblado en el servidor
WITH
permission_set = EXTERNAL_ACCESS

Creamos la funcion que llama a nuestro ensamblado y que servira para utilizar en nuestras consultas SQL:

CREATE
FUNCTION [dbo].[ObtenerWS](@id int, @texto [nvarchar](MAX))
RETURNS
[nvarchar](MAX) WITH EXECUTE AS CALLER
AS
EXTERNAL
NAME [CLRSP].[UserDefinedFunctions].[GetWebServices]

Puede que de un error de id de usuario si el propietario de la base de datos no es el mismo que el propietario de la base de datos master. PAra esto, hay que ponerlo con la siguiente instrucción:
--PONER EL USUARIO PROPIETARIO IGUAL A SA
ALTER AUTHORIZATION ON DATABASE::NAVSQL TO sa;

miércoles, 20 de noviembre de 2013

Consumir Web Services de Navision desde Reporting Services Parte 3

Puedes consultar las partes anteriores aquí:
parte 1 y parte 2
Ahora hay que crear el ensamblado.
Desde Visual Studio 2010 creamos un nuevo proyecto, seleccionamos el framework que previamente hemos averiguado.
Creamos un proyecto nuevo de Base de Datos (SQL Server) de tipo Visual C# SQL CLR Database Proyect. Nos pedira los datos de la conexion de nuestra base de datos.

Creamos una funcion GetWebServices que devuelve un sql-string y a la que se le pasa us entero y un string. Los tipos de datos que utilizaremos como podeis ver son los compatibles con el CLR de Sql. Por lo que un string pasa a ser un tipo de dato sqlstring. y asi sucesivamente con todos los tipos de datos.


En una clase aparte creamos un metodo que devuelva los valores que obtenemos al llamar a los WS de navision. Creamos la clase a la que pasaremos un integer y un string y que devolvera el valor de nuestra funcion de navision.

Agregamos los Web Services, uno por empresa para mediante un arametro seleccionar la empresa que desamos consultar desde SQL en Navision. La ruta de nuestro wsdl es:
http://SERVIDOR:7047/INSTANCIA/WS/EMPRESA/Codeunit/InterfaceWS
o si no tiene instancia:
http://SERVIDOR:7047/WS/EMPRESA/Codeunit/InterfaceWS

En las propiedades del proyecto ponemos el GUI que previamente hemos generado con la herramienta que incorpora el visual studio y marcamos la aplicacion como ensamblado visible para COM.
Ponemos esto en postbuild "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\sgen.exe" /force "$(TargetPath)"
No hay que olvidarse de los permisos que hay que darle al ensamblado para que posteriormente funcione. Como va a salir del ambito de SQL accediendo al servidor de navision, le daremos Permision Level=External.

 
Compilamos el proyecto y nos debe de haber generado la .dll y la XmlSerializers.dll dentro de bin:

jueves, 24 de octubre de 2013

Consumir Web Services de Navision desde Reporting Services parte 2

Puedes consultar las partes anteriores aquí:
parte 1
Lo siguiente que hay que hacer, es publicar el WEB service de Navision. Esto es muy sencillo realizarlo desde Navision y con unos sencillos pasos lo podemos completar.
Creamos primero nuestra CodeUnit llamada InterfaceWS:
 Creamos dentro de la CodeUnit una funcion llamada ConsultaExterna donde le pasamos un código y un texto (Por ejemplo):
 En la Tabla 2000000076 Web Service publicamos nuestra CodeUnit:
 Quedando tal que así:

En el próximo post crearemos la dll con Visual Studio 2010 para consumir este web service.

miércoles, 16 de octubre de 2013

Consumir Web Services de Navision desde Reporting Services


Algunas veces para realizar informes que muestren algún dato calculado de Navision, se da la enorme complejidad de cómo sacar el dato. Te planteas la necesidad de facilitar el trabajo a la hora de consultarlo. Mediante los WEB Services que expone Navision y el CLR que se integra en SQL podemos realizar informes en reporting services que consultan datos preparados por Navision.
La documentación es abundante sobre este tema, pero aquí pretendemos aglutinarla toda para tener un decálogo a seguir para crear-configurar y consumir los web services desde SQL.


Lo primero que hay que hacer es averiguar el FRAMEWORK que tenemos en nuestro servidor de SQL.
Para ello, ejecutamos la siguiente consulta:
--AVERIGUAR FRAMEWORK
select * from sys.dm_clr_properties
Una vez tenemos la versión del FRAMEWORK, hay que habilitar el servidor para que use la integración CLR. Por defecto, cuando se instala el SQL server, viene con esta opción deshabilitada, por lo que es casi seguro que tendrás que habilitarla:
--HABILITAR LA INTEGRACION CLR
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO
Ahora indicaremos al servidor  que la instancia de SQL Server confía en la base de datos y en su contenido mediante TRUSTWORTHY
--PONER COMO QUE CONFIA
ALTER DATABASE miDataBase
SET TRUSTWORTHY ON


Con esto hemos preparado la Base de Datos para que pueda trabajar con CLR . En próximos posts veremos como crear la dll, anexar el ensamblado a sql y utilizar nuestro ensamblado.

miércoles, 14 de agosto de 2013

Obtener el Servidor y la Base de Datos actual en SQL

Cuando queremos acceder a la Base de datos y/o Servidor actual por algún motivo (Bien sea una consulta por ADO o para ver las BBDD que tenemos creadas) C/AL nos lo pone muy sencillo al tener a nuestra disposición unas tablas virtuales que nos exponen estos datos:
NameDataTypeSubtype
recServerRecordServer
recDatabaseRecordDatabase

Pero cuando accedemos por web service nos da un error porque las tablas virtuales no tienen generados los metadatos para ser utilizadas por estos.
Una de las formas de conseguirlo es mediante el archivo Config de los web services donde esta indicado el servidor y la BBDD. El archivo es CustomSettings.config y esta en la carpeta de la aplicacion. Este archivo es un XML con los parametros de configuracion que los web services desplegan al iniciar el servicio.

NameDataTypeSubtype
recServerRecordServer
recDatabaseRecordDatabase
recUsuarioSQLRecordUsuario
cu50203CodeunitCodeSQL
DomDocAutomation'Microsoft XML, v4.0'.DOMDocument
DomNodeAutomation'Microsoft XML, v4.0'.IXMLDOMNode
MyServerNameText
MyBBDDNameText
//Comprobamos si es el WEB Service o no
IF ISSERVICETIER THEN BEGIN
  //Creamos un objeto XML para tratar el archivo config  IF ISCLEAR(DomDoc) THEN
    CREATE(DomDoc);
  

  //Cargamos el archivo config
  DomDoc.load(APPLICATIONPATH + 'CustomSettings.config');

  //Leemos Los Nodos
  DomNode := DomDoc.selectSingleNode('//appSettings/add[@key='DatabaseServer']');
  MyServerName := DomNode.attributes.item(1).text;
  DomNode := DomDoc.selectSingleNode('//appSettings/add[@key='DatabaseName']');
  MyBBDDName := DomNode.attributes.item(1).text;

END ELSE BEGIN

   //Si no es WEB Service lo hacemos de la manera tradicional
   recServer.RESET;
   recServer.SETRANGE("My Server",TRUE);
   IF recServer.FINDSET THEN BEGIN
       recDatabase.RESET;
       recDatabase.SETRANGE("My Database",TRUE);
       IF recDatabase.FINDSET THEN BEGIN
          MyServerName := recServer."Server Name";

          MyBBDDName :=recDatabase."Database Name";
       END;
   END;
END;


Con esto tenemos resuelto el problema.

miércoles, 7 de agosto de 2013

Poner el idioma de los web services en español

Con la arquitectura por capas que presenta navision, es posible que se genere alguna discordancia por configuraciones distintas en diferentes capas.
La que vamos a ver en este post es la referente a la configuracion de la capa de los web services. Es posible que instalemos la capa del servidor de navision en español y la capa de los web services los instalemos en ingles.
Esto puede parecer algo banal en principio, pero se puede convertir en un autentico quebradero de cabeza cuando trabajamos por ejemplo con fechas, en los web services las tratamos en formato mm/dd/aa y en el cliente clasico como dd/mm/aa.
No solo afecta en esto, tambien los calculos de fechas se ven afectados al tener que tratar con un lenguaje u otro.
Por ejemplo para calcular 1 semana en un idioma es 1S y en otro es 1W.

Para solucionarlo hay que seguir los siguientes pasos:

Instalamos el paquete de idioma español, esta en el cd de instalacion en la ruta Installers\ES\Server, con esto se instala el idioma. Una vez instalada se creara en el servidor dentro de la carpeta C:\Program Files (x86)\Microsoft Dynamics NAV\60\Service (La carpeta de los web services, la ruta puede variar) una carpeta es-ES y ESP.


 


Cuando se instalan los web services se configura en el servicio una cuenta de ejecucion que tiene que tener que ser un usuario con permisos en navision.

En la tabla 2000000073 se crea una entrada con el usuario de los web services y el idioma que queremos, que en nuestro caso es el español.


Vereis en muchas webs diferentes codificaciones, pero la que a mi me ha funcionado es la 1034.

Para finalizar, microsoft recomienda ejecutar la instruccion GLOBALLANGUAGE(1034); al menus una vez.
¿Que quiere decir esto? pues muy sencillo, crear una codeunit con una funcion que contenga la instruccion. Publicarla y ejecutarla desde nuestra aplicacion que consume los web services.

Con esto tendremos ambas capas en español.