Calling OTRS Web Services from .NET

In one of the current projects I have to connect to OTRS ticketing back-end.

OTRS is an open-source ticketing application and has a web service interface. I thought that querying the OTRS from NET should be straightforward because there were some examples for PHP that looked easy enough, but I was wrong.

logo[1]

The Symptoms

First of all, the WSDL descriptor for the web service has to be crafted almost by hand, as the generic interface for OTRS allows you to make your own web service interfaces, picking what operations you want to allow and how you should name them. It involved a lot of work for one of the customer IT guys 😉

The second stumble is that the SOAP interface for OTRS methods uses wrapped types, so you have to make the proxy class using SVCUTIL.EXE tool with /wrapped option against the WSDL.

The third problem was that choice types in WSDL is not supported by the WCF default serializer, and you have to "downgrade" it to the old XML serializer calling SVCUTIL.EXE with additional /serializer:XmlSerializer option, too.

Finally, I managed to make a call with the C# proxy client class against OTRS, but my joy was short-lived. The call to OTRS methods always returned null as a result.

The Cause

I fired up Fiddler to investigate the SOAP call. The call was made well and the OTRS responded in kind with a SOAP response filled with data. But, a slight mismatch was detected: the namespace of the response message element was not the same as the request message. Consequently, the NET proxy didn’t deserialize the message to the right type as the namespaces of the data type in NET and the SOAP response didn’t match.

The Solution

In the generated proxy class I looked up the method response data types. In one of them I found this attribute:

[System.ServiceModel.MessageBodyMemberAttribute(Namespace=http://request.contoso.com/operations, Order=0)]

and I changed it into

[System.ServiceModel.MessageBodyMemberAttribute(Namespace=http://response.contoso.com/operations, Order=0)]

Save, build, run and enjoy the correctly-deserialized response from OTRS.

Helpful links

http://stackoverflow.com/questions/7328631/system-invalidoperationexception-xmlserializer-attribute-system-xml-serializat

http://www.primordialcode.com/index.php/2008/10/15/invoking-javaaxis-web-service-net-return-null-issue/

[Reciclaje JavaScript] Fundamentos

Tal como dije en mi post del año pasado, una de las cosas que íbamos a aprender los desarrolladores de SharePoint con la nueva versión es precisamente a programar bien en JavaScript. Yo mismo me puse al día por necesidad y he descubierto que no es tan difícil programar bien JavaScript, si se entienden algunos conceptos clave. Mi idea en esta serie de posts es explicar estos conceptos de manera sencilla para que se entiendan bien. Intentaré no ser muy purista para no alejar la audiencia, que considero que tiene cierto conocimiento de JavaScript pero como una cosa totalmente auxiliar al código NET.

Puntos básicos de JavaScript

A pesar de su merecida o inmerecida fama de lenguaje “de juguete”, JavaScript es un lenguaje muy versátil y potente. Lo primero que hay que desaprender es que JavaScript no tiene nada que ver con Java (su nombre respondía a una estrategia de marketing de Netscape). JavaScript es un lenguaje funcional “vestido” de un lenguaje imperativo “tipo C”.

¿Funcional? Sí, en JavaScript las funciones son los reyes del mambo. Una función en JavaScript es objeto de primer nivel y se puede usar como resultado o parámetro de otras funciones. Una función puede tener parámetros pero éstos no son obligatorios cuando se invoca la función. Lo veremos todo más claro un poco más adelante, tened paciencia.

Tipos de datos

Todo lenguaje tiene una serie de tipos de datos básicos. JavaScript también. En esta tabla recogemos los tipos de datos de JavaScript:

Sencillos

Complejos

  • Number
  • String
  • Boolean
  • undefined
  • null
  • Object
  • Array
  • Function
  • RegExp
  • Date

A continuación voy a explicar las frikadas peculiaridades de cada tipo de datos, excepto RegExp y Data que son bastante especializados.

Wrappers

La mayoría de tipos en JavaScript se exponen dos veces: una como tipo primitivo y otra como “clase”. Por ejemplo, una cadena de texto en JavaScript es un tipo primitivo llamado string pero expone métodos como p.ej. toUpperCase() como si fuera un objeto. Realmente, hay un “objeto” de tipo String que encapsula (“wrapea”) un tipo primitivo string. Dicho esto, en JavaScript casi siempre es mejor usar el tipo primitivo que el tipo encapsulado, por tanto es mejor usar el constructor de objeto ({}) y de matriz ([]) y no los constructores new Object() y new Array().

Number

Todos los números en JavaScript son números decimales de 64 bits en coma flotante. Teniendo en cuenta esto, hay que usarlos muy cuidadosamente para cálculos intensivos, ya que las operaciones decimales siempre son mucho más lentas que los números enteros. Algunas implementaciones de JS optimizan el tipo de datos numérico a enteros cuando no hay decimales involucradas, pero siempre hay que partir de la base de que en JS los números son “caros” para realizar operaciones.

String

El texto se representa en JavaScript como Unicode. Podemos usar las comillas simples o dobles para incluir el valor literal de un string, pero hay que usar dos iguales. Si queremos “escapar” las comillas para incluirlas en el texto, basta con usar las comillas opuestas, p.ej. var textoConComillas = "texto ‘entre’ comillas";

Además, podemos codificar un string para incluirlo en la URL (que no permite ciertos caracteres) y para ello tenemos 2 instrucciones:

  • encodeURI / decodeURI de usan para direcciones URL/URI completas
  • encodeURIComponent / decodeURIComponent se usa para los valores de los parámetros en una URL/URI (es decir, los caracteres como & se escaparán)

Boolean

El tipo booleano tiene valores true o false (sin comillas). La diferencia es que en JavaScript todos los tipos de datos evaluan a un booleano. Es lo que se conoce como valores “truthy” o “falsey”.

Valores que evaluan a FALSE

Valores que evaluan a TRUE

  • false
  • 0 (cero)
  • "" o (cadena vacía)
  • null
  • undefined
  • NaN (resultado de división por cero)
  • todos los demás (incluso las cadenas de texto “false” o “0”)
  • objetos vacíos (p.ej. var a = {};)

De esta manera podemos simplificar las comparaciones: if(a == “” || a == undefined) pasa a ser if(a)

Undefined

Con esta piedra tropieza todo programador de NET en JavaScript. La regla más fácil para recordar es que undefined es una referencia nula en JavaScript. Si no declaramos una variable o la declaramos pero no le asignamos nada, en JavaScript esa variable será del tipo undefined.

Lo que es un null en NET, es undefined en JavaScript.

Null

A pesar de su parecido con NET, el null de JavaScript es un mero marcador de valor nulo que podemos poner para indicar que una variable no tiene un valor significativo, parecido al NULL de SQL.

Es importante saber que JavaScript nunca devolverá un null a no ser que lo pongamos nosotros a una variable.

Object

Tal como he mencionado anteriormente, los objetos en JS no son tan “fuertes” como en NET. No existe el concepto de clase ni de instancia.

Para instanciar un objeto podemos usar:

El constructor usando la notación “orientada a objetos” var a = new Object();
a.nombre = ‘Edin’;
El constructor literal usando la sintaxis JSON var a = { nombre: ‘Edin’ };
Una función, usando la palabra clave this para referirnos a la “instancia” actual de la función. var a = function()
{
this.nombre = ‘Edin’;
return this;
}();

En el último ejemplo hay dos paréntesis después de la declaración de la función. Son muy importantes. Sirven para ejecutar la función y devolver el resultado. Si no los ponemos, nuestra variable a sólo contendrá la definición de la función (es decir, será de tipo Function) y no el objeto que la función devuelve.

image image

¿Y si nos olvidamos de poner return this; dentro de la función? La función devolverá un objeto vacío (porque no hay ninguna clausula return) que no tiene definido el método (mejor dicho, la función) llamado "nombre". Por tanto, el typeof sería undefined. Es muy importante entender y asimilar este punto para evitar sorpresas con JavaScript.

Array

Las matrices (arrays) se definen en JS con un objeto Array o bien con el literal [] separando los elementos con comas. Empiezan siempre en la posición 0 y pueden contener elementos de tipos diferentes (no son tipadas). Incluso podemos tener funciones u otros arrays como elementos de un array.

El número de elementos de un array se obtiene con la propiedad length.

var array = [‘Edin’, 8.123, "Kapic"];
var longitud_array = array.length;

Function

Como hemos visto antes, las funciones son mucho más "maleables" en JavaScript que en NET. Hay dos maneras de declarar una función.

La primera y la más frecuente es usar la sintaxis NET y escribir una declaración:

function miFuncion(parametros)
{
  /* el código de la función */
}

La otra manera es asignar la función a una variable como una expresión:

var miFuncion = function (parametros)
{
  /* el código de la función */
};

Notad que cuando usamos una expresión, hay que poner punto y coma al final, ya que no deja de ser una asignación de un tipo de datos Function a una variable que se llama miFuncion.

Las dos maneras son equivalentes pero la primera (la declaración) tiene el efecto no deseado de hoisting. Se trata de que JavaScript automáticamente sube la declaración de la función arriba de todo el código JavaScript (mejor dicho hasta su contenedor más alto). Siempre que veamos una declaración, hay que imaginarse una variable con el nombre de la función, puesta arriba del todo e inicializada.

/* codigo */ function a() { … }  es lo mismo que var a = function() { … }; /* codigo */

En el ejemplo siguiente se observa el efecto pernicioso de hoisting:

function f() {
    /* es como si aquí pusiera: var g = function()… */
    var g = 1; 
    function g() {
        alert("hola");
   }
    g();
}

La función g() es una declaración, sube por encima de var g y por tanto se pierde al inicializar g con el valor numérico. La ejecución g() no será válida.

Si lo cambiamos a una expresión, entonces la última asignación de g será la de la función y todo funcionará tal como esperamos.

function f() {
    var g = 1; 
    var g = function() {
        alert("hola");
    }
    g();
}

Variable Hoisting

El maldito hoisting existe también para las variables. Si ponemos var nombre = valor en un código, JavaScript lo va a separar en dos al ejecutar: var nombre arriba del todo y nombre = valor en el sitio donde está la expresión.

var a = 1;
function abc() {
  alert(a);
  var a = 2;
}

devolverá undefined como resultado del alert, ya que es idéntico a este código:

var a = 1;
function abc() {
  var a; /* a = undefined */
  alert(a);
  a = 2;
}

Resumen

Con estos ejemplos espero haber cubierto la base para poder avanzar con JavaScript bien programado. En los próximos posts veremos más características de JavaScript moderno. Hasta entonces, practicad los ejemplos anteriores con JsFiddle y procurad de entender la idiosincrasia del JavaScript.

Lo que no sabías sobre Iberian SharePoint Conference 2013

Supongo que la mayoría de los lectores del blog ya saben de que va el asunto, pero desde hace tiempo quería hacer un post sobre ello. Pues aquí va, por fin explicado desde el principio que es todo esto de la “Iberian SharePoint Conference”.

El origen

Desde el año pasado, los chicos de SUG.CAT teníamos el “mono” de organizar un evento grande en Barcelona. Mi inspiración personal fue asistir al SharePoint Saturday Belgium en Bruselas. Los belgas organizaron un evento espectacular, más aún teniendo en cuenta que son cuatro gatos contados. Nos dijimos que aquí también podemos organizar eventos importantes y de allí nació la idea.

Luego involucramos al resto de los grupos de usuarios de SharePoint de España (MadPoint y LevaPoint), y por supuesto a SUGES, la proverbial madre del cordero. Quedó claro desde el principio que queríamos un evento a nivel peninsular, por lo que contamos con ponentes y grupos de usuarios portugueses.

Detalles logísticos

Al final del 2012 ya tuvimos una idea más o menos clara y decidimos el día para el evento. Lo tuvimos que mover varias veces pero al final se quedó en 10 de octubre del 2013.

A partir de aquí estuvimos buscando patrocinadores para hacerlo posible (y todavía estamos en ello). Tenemos a los grandes sponsors como K2, Beezy, KwizCom, Encamina o General de Software, con lo que podemos estar más tranquilos desde el punto de vista logístico/financiero. También contamos con un equipo de voluntarios que lo hacen posible.

http://edinkapic.azurewebsites.net/wp-content/uploads/2013/06/IberianSharePointConference-300x188.jpg

Ponentes

La otra tarea para asegurar una buena conferencia es buscar ponentes de calidad y que atraigan. Por ello tenemos los ponentes nacionales de primerísimo nivel:

  • MVPs locales: Juan Carlos González, Mario Cortés, David Martos, Alberto Díaz, Gustavo Vélez, Daniel Seara (y yo mismo)
  • Personas prominentes en la comunidad SharePoint local: Adrián Díaz, Miguel Tabera, Santiago Porras, José Quinto, Ibon Landa
  • Estrellas invitadas del otro lado del charco: Fabián Imaz y Ricardo Muñoz
  • Estrellas invitadas de fama mundial: Joel Oleson, Christian Buckley, Mark Miller, Michael Noel

Con tal despliegue de ponentes, creo que los asistentes estarán muy contentos con lo que ven a ver y escuchar en la conferencia. Estamos trabajando para preparar una agenda para todos los gustos, con múltiples tracks de sesiones (desarrollo, administración, negocio etc). Podéis ver las sesiones propuestas aquí.

Talleres post-conferencia

Además, el día 11 de octubre por la mañana haremos dos cursos-talleres: uno para desarrolladores y otro para administradores de SharePoint. Los talleres serán impartidos por los MVPs de SharePoint y se pagarán aparte. La idea es que los asistentes aprovechen la visita y se formen con los mejores, en un curso de alto nivel.

¡Ahora te necesitamos a tí, lector!

  • Si no lo has hecho ya, pre-regístrate en la web de la conferencia
  • Si tienes compañeros o amigos que están en el mundo SharePoint, comparte con ellos la información y que también se apunten
  • Si tu empresa podría estar interesada en patrocinar el evento, escríbenos

Review of “The Art of Community” (2nd Edition)

It took me much more time to finish The Art of Community (2nd Edition): Building the New Age of Participation than usual, due to my recent lack of significant commuting as I had no spare time to read much. However, I did finish it and I want to share my two cents about it.

I started with no prior knowledge of the author, Jono Bacon. My initial fears about the author were quickly removed by reading the first chapter. Jono has good story-telling skills and the prose is never boring or too verbose. The entire book is packed with real-life anecdotes and references and it’s not hard to read, even if you are not a techie type.

This said, in some parts I felt that the book was leaning too much on the “open-source software community” side of things but even that is understandable, given the author experience in those communities. I felt that although he tried to write the book for all kinds of communities, the most compelling examples were the ones he drew from his experience. If there’s one thing to improve in the book, it would be this one.

I run a user group, so I was eager to find quick tips and tricks. I did not. The reason was that the book taught me that raising and running a community is neither a one-shot thing nor one-man endeavour. Jono outlines a strategic approach to the community that makes you and your fellow members find the higher purpose for the community, make the long and short-term goals and then enable collaboration and communication to achieve these goals. The book is not a recipe book but a “make your own recipe” book. I really enjoyed the breadth of topics that follow the strategy for a community: how to make decisions, how to contribute, how to design the processes and streamline them, how to manage the conflicts etc. I learned a lot from these chapters.

One of the interesting chapters for me was the chapter on running events. Even if I have some experience in the event organization, still I found very important pointers in it.

At the end of the book there is a collection of interviews with fellow community managers, providing real-life supplement to the theory present in the book. The people interviewed are very different, from Tim O’Reilly (yes, the O’Reilly guy) to Dries Buytaert of Drupal.

All in all, I’d wholeheartedly recommend the book for any current or aspiring community leader/manager/founder/wannabe, even despite the occasional open-source software community bias. The first version of the book is available as a free download, so you are not far away from the reading experience!

Building a Document Routing Hierarchy with SharePoint Subsites and Content Organizer

In this occasion I have been exploring the possibility of an auto-organizing document hierarchy in SharePoint 2010, made with Content Organizer functionality. As you may recall, the Content Organizer allows the documents to be routed according to rules that use metadata to decide where the document should go. This greatly enhances the usability of a document repository in SharePoint, as the end users don’t have to know where exactly should the document be uploaded. By leveraging the content organizer rules, we automate the exact logistic organization of the documents and significantly lower the possibility of incorrect classification.

Content Organizer out-of-the-box

The straightforward Content Organizer works great when you cope with different document libraries on a single site. You get one “Drop Off Library” where you should upload the documents to. Once uploaded there, the documents will be routed to the right document library and optionally inside a specific folder.

The user interface for dropping a document in Content Organizer notifies you that the document will be routed:

image

As you can see in the Content Organizer Rule editor, we only get local site lists and libraries as the destination option:

image

What happens when you have a hierarchy that spans multiple subsites that all share the same base content type but are strictly separated in different subsites for security reasons? Well, in this case you have to tweak the Content Organizer a bit to accommodate the subsites.

Routing Documents to a different site

In order to allow a content organizer to route a document to a different site, you have to create a “Send To” connection in the Central Administration. Go to “General Application Settings”, then choose “Configure send to connections” in “External Service Connection” section. In this page you will have to add the absolute path of the content organizer service of the site that you wish to route the document to. The URL is always the same:

  •  Site URL followed by /_vti_bin/officialfile.asmx

In this example, there is a subsite called “Global” and the “send to” connection" called Global is created. Please remember that the Send To Connections configuration is stored for each web application, so make sure that you are changing it for the right web application.

image

Once you have the Send To connection registered in Central Administration, you have to change two things in the site that you wish to be the entry point to the system. Go to “Site Settings”, “Content Organizer Settings” and make sure that the checkbox “Sending to Another Site” is set.

SNAGHTML1c7e8ab7

Now you can go to “Site Settings”, “Content Organizer Rules” of the site and create a rule that can target another site.

image

There is one limitation to this approach: you can target a different site but you can’t target a specific document library on that site. The document will be routed to the Content Organizer on that site and its rules will be enforced. So, in order to overcome this limitation you have to add a rule on the destination site that will route the document into a specific document library.

As it begins to become a little tricky to explain in words, I’ll draw a quick diagram to explain how my system works:

image

I add the routing rules to the Root Site that will send the newly uploaded document to the correct site, according to a Type column (in my case it’s a Managed Metadata column but it could be any type of column that can be compared to). When the document arrives to the Content Organizer on the destination site, I put two simple rules there:

  • If the Type of the document is the correct one, I move the document to the corresponding document library
  • If the Type of the document is not the correct one, I route the document again to the Root Site

The purpose of this loop is to minimize the number of rules for the correct classification. If the user uploads a Sales document on a HR site, I’d have to write the rule that moves it to the Sales site. By keeping all the routing logic for the different site at the Root Site level, I just have to send the document to the root site in order to get classified correctly.

Note: this setup can cause infinite loop if you mess with the rules and conditions, so please double-check them.

PowerShell to the Rescue

So, we have seen how to organize a multiple-site hierarchy with the Content Organizer feature. I admit that the only boring thing in the whole process is the act of building the “Send To” connections by hand. I have created a tiny PowerShell script that will do that for you. It will parse the given web application URL, iterate over all the sites in the site collections and then will add the sites with active Content Organizer to the “Send To” connections.

image