Sharepoint Online

Dentro de la visión de Microsoft en el modelo de cloud computing Sharepoint se presenta como una de sus piezas. Sharepoint Online es el servicio que nos ofrece Microsoft para todos aquellos necesiten de entornos colaborativos, gestión documental, contenidos y quieran utilizar esas funcionalidades como servicios en lugar de implantarlo en sus infraestructuras.

Sharepoint Online NO es un hosting de MOSS, eso lo podemos encontrar en www.SharePointHosting.com, Sharepoint Online nos permitirá disponer de alguna de las funcionalidades de MOSS pero con una serie de ventajas adicionales de manera que paguemos por el servicio consumido y no por los recursos utilizados. Podéis adquirir una licencia trial de hasta 20 usuarios en http://www.microsoft.com/online/ además encontrareis toda la información necesaria en cuanto a costes y modo de contratación.

Os dejo una presentación con la que estoy trabajando para mayor claridad a estos conceptos, además los iré elaborando más en detalle durante estos días.

Podéis bajaros además la guía Microsoft SharePoint Online Standard Developer Guide para personalizar el servicio y para entender mejor la forma de licenciamiento Microsoft_Online_Subscription_Program.

 
Los principales ventajas que podemos obtener de Sharepoint Online son:
  • Nos olvidamos del mantenimiento y su instalación, Sharepoint se aloja en los centros de datos de Microsoft por lo que empezaremos a utilizar el servicio al terminar de aceptar el contrato de subscripción.
  • No podemos realizar despliegues de soluciones, al estar en una plataforma compartida para poder garantizarnos el servicio no podremos subir soluciones wsp ni features. La forma de personalizarlo será mediante Sharepoint Designer.
  • Disponibilidad 24×7, Microsoft nos garantiza la disponibilidad del servicio, se encarga de realizar backups cada 12h y es capaz de restaurarlo por nosotros en caso de necesitarlo.
  • Bajo riesgo de inversión, se adquiere mediante subscripciones que se abonan mensualmente. No necesitaremos de una gran cantidad de dinero para empezar a utilizarlo.
  • Cada usuario debe disponer de una subscripción, por lo que no podremos utilizarlo para crear webs públicas.
  • Geodistribución.

 

Disponemos de tres portales distintos:

  • Customer portal, desde el que gestionamos las subscripciones de nuestra empresa.
  • Adminsitration center, configuramos los servicios contratados, usuarios que van a poder trabajar, creamos las colecciones de sitio.
  • My  company portal, está destinado a los usuarios finales, desde donde tendrán acceso a los servicios que les hayan habilitado desde el Administration center.

 

 image image

 

 

image image

 

image

 

En estos días iremos viendo como personalizarlo y las opciones que dispondremos para configurar el servicio.

Sharepoint faulting module kernel32.dll

Al entrar en mi aplicación web de repente me encuentro con que me empieza a pedir las credenciales continuamente y nunca llega a cargar la aplicación hasta que al final me devuelve un error. Al entrar en el log de eventos de windows me encuentro con el siguiente error:

Tipo de suceso: Error
Origen del suceso: .NET Runtime 2.0 Error Reporting
Categoría del suceso: Ninguno
Id. suceso: 1000
Fecha:  28/04/2009
Hora:  17:34:03
Usuario:  No disponible
Equipo: SAPDGACMAD-602
Descripción:
Faulting application w3wp.exe, version 6.0.3790.3959, stamp 45d69572, faulting module kernel32.dll, version 5.2.3790.4062, stamp 4626451c, debug? 0, fault address 0x0000000000027d8d.

 

Al entrar en cualquiera de las aplicaciones web de sharepoint incluso la administración central también se producía este error. Lo más curioso de todo es que al abrir la consola de configuración de sharepoint de repente se cerraba!!!.

Lo primero que pensé “bufff, un virus”, después “buffff se ha jodido el framework”.

Después de pasar el antivirus, instalar/desinstalar el FW 3 y el 2, al final se me ocurrió la feliz idea de intentar ejecutar un comando STSADM y al ejecutarlo me devuelve un mensajito del tipo “StackOverFlowException”. Al parecer alguna tarea de administración (Borrar un subsitio desde el Shaepoint Manager) había estropeado la bbdd de configuración.

Por lo que la solución fué cambiar de nombre a la bbdd de configuración de Sharepoint y arrancar el programa de configuración de sharepoint, al no encontrar la bbdd me dejó desacoplar el servidor y volver a configurarlo, pero esta vez con la bbdd restaurada.

 

Lo mejor de todo es que estaba elaborando en ese momento un plan de contingencia, menos mal que fue en un entorno de pruebas.

[Infopath] Resumen

Cierro con este post la temática de este último mes acerca de Infopath orientado al desarrollo como ya hice con [Sharepoint] Introducción al desarrollo.

 

Empezando con Infopath

Introducción al concepto de Infopath

Infopath Form Services y Office Forms Server

Explicación de las distintas versiones y licenciamiento.

Formularios con Infopath

Cómo diseñar formularios y manejar los controles.

[Infopath] Orígenes de datos

Cómo manejar los distintos orígenes de datos.

[Infopath] Mostrar un formulario desde un WebPart

Como configurar el XmlFormView para visualizar un formulario infopath desde un webpart.

[Infopath] Control de selección de usuario

Cómo agregar un control para seleccionar un usuario del dominio.

Programando en Infopath

Cómo empezar a programar con Infopath

como hacer un DrillDown

Post de Álvaro Arias acerca de cómo encadenar combos de selección con Infopath.

[Infopath] Promoción de propiedades

Concepto y ejemplos.

Internacionalización con Infopath

Ejemplos con distintos formatos de fecha y decimales.

 

Recursos

Microsoft Office Forms Server 2007 SDK

TechCenter de Microsoft Office Forms Server

InfoPath Team Blog

InfoPath Forms for Workflows

 

Libros

Designing Forms for Microsoft Office InfoPath and Forms Services 2007

Visual Studio Team Test Quick Reference

El equipo de Rangers de Visual Studio Team System ha publicado en codeplex una guía en modo How to’s para trabajar con los webtest y pruebas de carga.

Los capítulos principales son:

  • SETUP CONSIDERATIONS 9
  • WEB TEST CONSIDERATIONS 14
  • WEB SERVICE TEST CONSIDERATIONS 35
  • UNIT TEST CONSIDERATIONS 36
  • LOAD TEST CONSIDERATIONS 42
  • LOAD TEST RIG CONSIDERATION 56
  • PERFORMANCE DATA COLLECTION AND USAGE 66
  • LOAD TEST RESULTS STORE INFORMATION 73
  • TEST CUSTOMIZATION 76
  • ITEMS CHANGED OR FIXED IN VSTS 2008 SP1 77
  • GENERAL COMMANDS AND TRICKS (NOT VSTS SPECIFIC) 79

Internacionalización con Infopath

La internacionalización en Infopath nos permite diseñar formularios para distintos idiomas y formatos. El problema lo tenemos cuando trabajamos con campos de fecha, decimales o campos moneda. Infopath nos permite definir como se visualizarán estos campos en tiempo de diseño y en ejecución. No es lo mismo “100.2” que “100,2”, tampoco es lo mismo “30/03/2009” que “03/30″/2009”.

Cuando diseñamos nuestra plantilla podemos definir el idioma para todos los controles, esto hará que aquellos controles que hereden de las propiedades definidas en la plantilla se comportarán en función del idioma indicado.

El idioma de la plantilla lo establecemos  desde Opciones del formulario > Examinar > Idioma del formulario. Si no especificamos ninguno, por defecto aplicará el definido regionalmente en el equipo sobre el que se ejecute.

Sobre cada control además podemos definir en que formato queremos que se visualice.

Para los campos del tipo fecha podemos mostrar directamente el valor almacenado en xml, indicar un formato específico o que el formato sea el indicado por la cultura regional.

Para los campos de tipo decimal o doble, podemos definir el número de dígitos decimales y el separador de millares.

image image

 

Para verlo con más claridad he diseñado una plantilla que muestra un campo de tipo fecha y numérico en distintos formatos:

  • El 1º muestra el valor xml
  • El 2º muestra la fecha en función de la zona definida
  • La 3º muestra la fecha en formato DD/MM/YYYY
  • El 4º y 5º muestran un control fecha asociado a un campo del tipo texto.
  • El 6º muestra el valor decimal almacenado en el xml.
  • El 7º muestra con separadores
  • El último muestra sin separadores de millares

 

En Español:

image

En Inglés:

image

 

Y cómo afecta la internacionalización al xml generado?, si abrimos el xml generado en los dos casos veremos que tenemos un xml similar:

Español:

<?xml version=”1.0″ encoding=”UTF-8″?><?mso-infoPathSolution solutionVersion=”1.0.0.5″ productVersion=”12.0.0″ PIVersion=”1.0.0.0″ href=”file:///C:UsersAdministradorAppDataLocalMicrosoftInfoPathDesigner2e706af73eab64283manifest.xsf” ?><?mso-application progid=”InfoPath.Document” versionProgid=”InfoPath.Document.2″?><my:misCampos my:Fecha2=”2009-04-24″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:my=”http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-04-20T21:11:49″ xmlns:xd=”http://schemas.microsoft.com/office/infopath/2003″ xml:lang=””>
    <my:Fecha1>2009-04-11</my:Fecha1>
    <my:Decimal1>1234567.89</my:Decimal1>
</my:misCampos>

Inglés:

<?xml version=”1.0″ encoding=”UTF-8″?><?mso-infoPathSolution solutionVersion=”1.0.0.5″ productVersion=”12.0.0″ PIVersion=”1.0.0.0″ href=”file:///C:UsersAdministradorAppDataLocalMicrosoftInfoPathDesigner2e706af73eab64283manifest.xsf” ?><?mso-application progid=”InfoPath.Document” versionProgid=”InfoPath.Document.2″?><my:misCampos my:Fecha2=”2009-04-09″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:my=”http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-04-20T21:11:49″ xmlns:xd=”http://schemas.microsoft.com/office/infopath/2003″ xml:lang=””>
    <my:Fecha1>2009-04-15</my:Fecha1>
    <my:Decimal1>12345678.67</my:Decimal1>
</my:misCampos>

De modo que si queremos manejar estos valores en los tipos nativos de .NET podemos hacer lo siguiente:

Para las fechas podemos utilizar directamente “DateTime.parse”.

Para los decimales o dobles tendremos que utilizar “double.parse” pero especificando el idioma ingles. Si quisiéramos realizar una validación desde infopath podríamos hacer algo como esto:

public void Decimal1_Validating(object sender, XmlValidatingEventArgs e)
        {
            if (!string.IsNullOrEmpty(e.NewValue))
            {
                System.Globalization.CultureInfo en = new System.Globalization.CultureInfo(1033);
                double valor = double.Parse(e.NewValue, en);
            }
        }

 

Y qué pasa si abrimos un fichero xml generado con una plantilla en un idioma y lo abrimos en otro idioma?, pues que infopath convertirá automáticamente los valores sin lanzar ninguna excepción.

[Infopath] Promoción de propiedades

Nos queda por ver como relacionar los formularios infopath con Sharepoint más allá de la visualización. Para ello vamos a ver la promoción de propiedades y como manejar el elemento generado mediante un EventHandler desde Sharepoint.

La promoción de propiedades consiste en extraer los valores de ciertos campos del formulario para utilizarlos en otro entorno como por ejemplo sharepoint, pudiendo manejarlos en vistas, búsquedas, workflows, etc.

Si continuamos con nuestro ejemplo de notas de gasto de los anteriores post, promocionarnos la propiedad del campo “estado” para controlarlo desde un EventReceiver y así controlar que no se pueda editar el documento una vez entregado.

Al guardar los datos de un formulario infopath podremos indicarle que lo haga sobre una biblioteca de documentos de Sharepoint, que llame a un servicio web, que lo envíe por correo o que lo envíe en modo post a a una páginas web. En sharepoint lo guardaremos en una biblioteca de formularios. Al guardar el formulario, infopath creará sobre la biblioteca indicada un fichero xml con los datos introducidos. Podemos entonces asociar a la biblioteca un EvenReceiver, un Workflow o promocionar propiedades.

Asociaremos entonces un EvenReceiver sobre la biblioteca que tenía asociada la plantilla xsn con nuestro formulario. Este EvenReceiver controlará el estado de la nota de gasto de forma que una vez la hayamos entregado no podamos volver a editarla. Hasta ahora no habíamos definido ningún campo “estado” en nuestra plantilla, por lo que ¿cómo lo agregamos para que podamos leer desde el formulario infopath y el EvenReceiver de sharepoint?, pues con la promoción de propiedades. Básicamente consiste en indicar tanto a sharepoint como a infopath que camos del origen de datos principal se va a compartir. Para infopath la propiedad promocionada será como un campo más del origen de datos principal, y para sharepoint corresponderá con una nueva columna en la biblioteca donde se aloje la plantilla xsn.

Abrimos entonces nuestro fichero EjemploNotasDeGasto.xsn en modo edición. Agregamos un campo al origen de datos principal un nuevo campo con el nombre “Estado” del tipo texto, además marcaremos que se pueda editar el campo desde una venta de propiedades.

A continuación publicamos nuestra plantilla sobre una biblioteca de documentos, en esta ocasión lo he publicado como plantilla de una biblioteca de formularios con compatibilidad de explorador. Es importante que antes de publicar indiquéis en las propiedades de la plantilla que determine el nivel de seguridad automáticamente.

Una vez indicada la biblioteca os aparecerá una pantalla con el siguiente aspecto, sobre la que agregaremos una nueva columna sobre la que indicaremos la relación entre la columna de la biblioteca con el campo del origen de datos del formulario infopath.

image

Una vez publicado nuestra plantilla xsn veremos en las propiedades de nuestra biblioteca  una nueva columna:

image

Con VisualStudio creamos un EvenReceiver y lo asociaremos a la biblioteca de forma que cuando el usuario rellene el campo “Responsable” cambiemos el valor del campo “Estado”.

Pero fijaros que el responsable no es una propiedad promocionada, entonces ¿cómo leemos los datos xml generados por infopath para conocer los valores del Responsable?:

  • Promocionando la propiedad
  • Leyendo los datos guardados por infopath en modo xml

 

Si abrimos el fichero xml generados por la plantilla encontraremos algo comoe sto:

<?xml version=”1.0″ encoding=”utf-8″?>
<?mso-infoPathSolution name=”urn:schemas-microsoft-com:office:infopath:Plantilla1-2:-myXSD-2009-03-20T16-27-26″ solutionVersion=”1.0.0.29″ productVersion=”12.0.0.0″ PIVersion=”1.0.0.0″ href=”http://w2k3r2:17092/FormServerTemplates/Plantilla1_2.xsn”?>
<?mso-application progid=”InfoPath.Document” versionProgid=”InfoPath.Document.2″?>
<my:misCampos xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:my=”http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-03-20T16:27:26″ xmlns:xd=”http://schemas.microsoft.com/office/infopath/2003″ xml:lang=”es-ES”>
    <my:txtNombre>Mario</my:txtNombre>
    <my:txtEmail>mcortes@renacimiento.com</my:txtEmail>
    <my:txtApellidos>Cortés flores</my:txtApellidos>
    <my:txtNumeroEmpleado>338877</my:txtNumeroEmpleado>
    <my:grupo1>
        <my:grupo2>
            <my:txtFecha>2009-04-02</my:txtFecha>
            <my:txtImporte>11</my:txtImporte>
            <my:tipoDeGasto>Taxi</my:tipoDeGasto>
        </my:grupo2>
    </my:grupo1>
    <my:txtObservaciones></my:txtObservaciones>
    <my:gpResponsable>
        <my:Responsable>
            <my:DisplayName></my:DisplayName>
            <my:AccountId></my:AccountId>
            <my:AccountType></my:AccountType>
        </my:Responsable>
    </my:gpResponsable>
</my:misCampos>

Si accedemos por código al objeto SPListItem que representa el elemento almacenado dispondremos de la propiedad “File” que podremos leer abriendo un stream de la siguiente forma:

XmlDocument xmlNotaDeGasto = new XmlDocument();
XmlTextReader xmlTextReader = new XmlTextReader(properties.ListItem.File.OpenBinaryStream());
xmlNotaDeGasto .Load(xmlTextReader );

Una vez cargado los datos como un XmlDocument accederemos al campo “my:AccountId” para leer el valor. El problema vendrá cuando intentemos acceder por ejemplo con el método “SelectSingleNode”, obtendremos una excepción pidiéndonos un “XmlNamespaceManager”, si lo creamos y lo pasamos a SelectSingleNode obtendremos otra excepción del tipo “unrecognized ‘my’ prefix”. Para solucionarlo crearemos el XmlNamespaceManager de la siguiente forma:

 

public XmlNamespaceManager InitNamespaceManager(XmlDocument xmlDOMDoc)
{
      XmlNamespaceManager xnmMan;

      xnmMan = new XmlNamespaceManager(xmlDOMDoc.NameTable);

      foreach (XmlAttribute nsAttr in xmlDOMDoc.DocumentElement.Attributes)

      {

            if (nsAttr.Prefix==”xmlns”)

                  xnmMan.AddNamespace(nsAttr.LocalName,nsAttr.Value);

      }

      return xnmMan;

}

 

Para crear el EvenReceiver he utilizado las extensiones VseWSS 1.3 y el código quedaría una cosa así:

public class NotasDeGastoItemEventReceiver : SPItemEventReceiver
   {
       public NotasDeGastoItemEventReceiver()
       {
       }

       public override void ItemAdding(SPItemEventProperties properties)
       {
           ItemUpdating(properties);
       }

       public override void ItemUpdating(SPItemEventProperties properties)
       {
           try
           {
               if (string.IsNullOrEmpty((string)properties.ListItem[“Estado”]))
               {
                   XmlDocument xmlNotaDeGasto = new XmlDocument();
                   XmlTextReader xmlTextReader = new XmlTextReader(properties.ListItem.File.OpenBinaryStream());
                   xmlNotaDeGasto.Load(xmlTextReader);
                   XmlNode nodoAccountResponsable = xmlNotaDeGasto.SelectSingleNode(“//my:AccountId”, InitNamespaceManager(xmlNotaDeGasto));
                   string nuevoEstado;
                   if (!string.IsNullOrEmpty(nodoAccountResponsable.InnerText))
                       nuevoEstado = “Publicado”;
                   else
                       nuevoEstado = “Borrador”;

                   DisableEventFiring();
                   try
                   {
                       properties.ListItem[“Estado”] = nuevoEstado;
                   }
                   finally
                   {
                       EnableEventFiring();
                   }
               }
           }
           catch
           {
               properties.ErrorMessage = “Se ha producido un error que impide la modificación”;
               properties.Status = SPEventReceiverStatus.CancelWithError;
           }
       }

       public override void ItemDeleting(SPItemEventProperties properties)
       {
           if (!string.IsNullOrEmpty((string)properties.ListItem[“Estado”])&&
               (string)properties.ListItem[“Estado”] != “No iniciado”      &&
               (string)properties.ListItem[“Estado”] != “Borrador”)
           {
               properties.ErrorMessage = “La nota de gasto no puede borrarse”;
               properties.Status = SPEventReceiverStatus.CancelWithError;
           }
       }

       #region “Helper”
       public XmlNamespaceManager InitNamespaceManager(XmlDocument xmlDOMDoc)
       {
           XmlNamespaceManager xnmMan;
           xnmMan = new XmlNamespaceManager(xmlDOMDoc.NameTable);
           foreach (XmlAttribute nsAttr in xmlDOMDoc.DocumentElement.Attributes)
           {
               if (nsAttr.Prefix == “xmlns”)
                   xnmMan.AddNamespace(nsAttr.LocalName, nsAttr.Value);
           }
           return xnmMan;
       }
       #endregion “Helper”

   }

Por último nos queda controlar desde el formulario que solo se pueda abrir en modo edición cuando el valor del campo estado no sea “No entregado” o “Borrador, (en este caso no lo vamos a hacer por programación sobre Infopath), bloquearemos los controles usando los “formatos condicionales”. Desde las propiedades de cada uno de los controles desde la pestaña “Presentación” > formato condicional > agregar.

image

Programando en Infopath

Hasta ahora solo hemos visto de Infopath ha sido desde el diseñador, toca mojarse un poquito con el código. ¿Podemos escribir código en un formulario Infopath para que actúe de acuerdo a una lógica de negocio?, pues sí, para éllo Infopath utiliza las VSTA (Microsoft Visual Studio Tools for Applications). Con VSTA podremos programar en Visual Basic .NET o c# de forma integrada con el formulario que estemos diseñando. Todo lo que desarrollemos generará una dll que irá incrustada en nuestra plantilla xsn. Si utilizamos Infopath Forms Services al subir nuestra plantilla a Sharepoint se desplegará automáticamente una solución wsp de sharepoint con todos los elementos de nuestro formulario y lo mejor de todo es que además deplegará la dll necesaria para ejecutar nuestro código.

Empezando con las VSTA

Lo primero que necesitamos son las VSTA, aunque tengamos instalado Visual Studio las vamos a tener que instalar, si no lo hacemos nos encontraremos un mensaje de error del tipo: “Infopath no puede iniciar Microsoft Visual Studio Tools para aplicaciones”

VSTA1

Para instalarlo necesitaremos tener el Framework 2.0 y habilitar el paquete desde el setup de nuestro infopath u office seleccionando el elemento “Infopath > Compatibilidad con programación .net > Compatibilidad con programación .net para .net framework versión 2.0 > Visual Studio Tools para aplicaciones.

VSTA2

 

Una vez instalado antes de empezar a tirar líneas debemos pensar donde vamos a alojar el código generado. Desde herramientas > opciones del formulario > programación encontraremos una ventana con las opciones disponibles, en nuestro caso elegiremos el lenguaje .net en el que generaremos el proyecto y el path físico donde se alojará el proyecto de las VSTA.

Este paso es importante ya que por defecto viene en visual basic y en la carpeta “Mis documentos”. Además cuando publiquemos la plantilla se incrustará la dll ya compilada pero no el código del proyecto, por lo que si copiamos a otro equipo solo el xsn no estaremos copiando los fuentes pudiendo llegar a perderlos.

Manejar eventos en infopath

Aunque podemos definir reglas y condiciones desde el diseñador (“no se por qué”) siempre hay alguna condición que debemos escribir mediante código. Usaremos el manejo de eventos de infopath para validar las entradas del formulario.

Continuando con el anterior ejemplo [Infopath] Control de selección de usuario, incluiremos por ejemplo una validación en la caja de importes para controlar que no se introduzcan importes superiores a 1000€. Seleccionando con el botón derecho la caja Programación > Evento Validating

Al seleccionarlo se abrirá una ventana de visual studio con el siguiente aspecto:

image

Lo primero que debemos saber es que no un Visual Studio normal, si vamos a la ayuda y vemos la versión veremos que es un Visual studio 2005 especial.

Otra cosa a destacar es que en la ventana de exploración no disponemos de un elemento solución solo disponemos del proyecto dll con las referencias a las VSTA y a infopath. Si luego buscamos en el path indicado para los fuentes veremos que realmente hay un fichero .sln que nos será muy útil.

También destacamos el fichero .snk necesario para que la dll tenga un strongname y pueda registrarse con un publickey.

Vemos también que no disponemos de un evento “Onload” sino que disponemos del método “InternalStartup” desde el que registraremos todos los eventos que desearemos capturar en el formulario en tiempo de ejecución. Esto se debe a que nuestra clase hereda de Microsoft.Office.InfoPath.XmlFormHostItem.

Siguiendo con el ejemplo, vemos que el evento de validación generado recibe un parámetro XmlValidatingEventArgs con la referencia al elemento de nuestro origen de datos principal el cual a generado el evento. En mi caso el ejemplo quedaría:

        public void txtImporte_Validating(object sender, XmlValidatingEventArgs e)
        {
           if(!string.IsNullOrEmpty(e.NewValue))
               if (double.Parse(e.NewValue) > 1000)
               {
                   e.ReportError(e.Site, false, “El importe debe ser inferior a 1000€”);
               }
        }

Para probarlo podremos hacerlo desde la opción de ejecución de Visual Studio o desde la vista previa del diseñador del cliente Infopath.

 

Otro de los eventos que podemos controlar es el del envío de los datos al servidor al hacer Submit.

Desde el evento InternalStartup agregaremos una línea del tipo:

EventManager.FormEvents.Submit += new SubmitEventHandler(Form_Submit);

donde “Form_Submit” es el nombre de mi método para capturar el evento. En mi ejemplo voy validar que la suma de todos los importes no supere los 3000€ quedando un código similar al siguiente:

public void Form_Submit(object sender, SubmitEventArgs e)

{

    XPathNavigator navigator = MainDataSource.CreateNavigator();

    XPathNodeIterator importesSolicitados = navigator.Select(“/my:misCampos/my:grupo1/my:grupo2”, this.NamespaceManager);

    double importeTotal = 0.0;

    foreach (XPathNavigator importeSolicitado in importesSolicitados)

    {

        string stImporte = importeSolicitado.GetAttribute(“txtImporte”, “”);

        importeTotal += double.Parse(stImporte);

    }

    if (importeTotal > 3000.0)

    {

                e.CancelableArgs.Cancel = true;

                e.CancelableArgs.Message = “El importe total de los gastos no debe superar los 3000€”;

    }

}

 

Si quisiéramos manejar el evento de carga del formulario utilizaríamos en el InternalStartup algo similar a lo siguiente:

EventManager.FormEvents.Loading += new LoadingEventHandler(FormEvents_Loading);

 

Manejar los orígenes de datos

Como vimos en el post [Infopath] Orígenes de datos disponemos de varios tipos de orígenes de datos en Infopath.

Para acceder al origen de datos principal utilizaremos la propiedad “MainDataSource”.

Para acceder a los orígenes externos utilizaremos la propiedad DataSources y accederemos a los orígenes mediante el nombre indicado en el diseñador, por ejemplo:

DataSources[“TiposDeGastos”]

Álvaro Arias nos muestra un ejemplo de como hacer un DrillDown de combos con infopath.

 

Depurar una plantilla infopath compleja

Cuando trabajemos con plantillas con orígenes externos nos será muy difícil depurar directamente desde el cliente infopath. Una alternativa consiste en abrir la solución generada por VSTA directamente desde Visual Studio en lugar desde Infopath, generar la dll en debug y sustituir el assembly, y depurarlo atacando al proceso w3wp.

El fichero sln de la solución lo encontraremos en la carpeta física establecida en la configuración de programación de la plantilla.

Para sustutir el assembly que depliega Infopath Form Services tenemos que buscar la feature instalada físicamente ya que no lo registra en el GAC. Un truco es buscar la característica de colección instalada, darle a desactivar y en la pantalla de confirmación en la url tendremos un parámetro FeatureId con el nombre de la carpeta que contiene nuestra dll a sustituir.