Welcome to MSDN Blogs Sign in | Join | Help

El adaptador de WSS es utilizado para enviar información desde BizTalk hacia liberias de SharePoint. Una de las funcionalidades que soporta el adaptador, además de enviar un mensaje como tal, es la posibilidad de asignar valores a columnas definidas en dicha libreria (ya sean nativas de Sharepoint o definidas por el usuario).

Estas columnas pueden ser especificadas de 3 formas:

La primera forma es especificando las columnas a las que se desea dar valores directamente en la configuración del puerto mismo, como muestra la siguiente figura:

image

 

Una segunda forma es definiendo las columnas programaticamente en una orquestación de BizTalk o un componente del Pipeline. Para esto, el adaptador de WSS soporta una propiedad del contexto del mensaje WSS.ConfigPropertiesXml, la cual contiene un XML con la definición y valores de las columnas:

strConfig = "<ConfigPropertiesXml>";
strConfig = strConfig + "<PropertyName1>Error Message</PropertyName1>";
strConfig = strConfig + "<PropertySource1>" + sDescription + "</PropertySource1>";
strConfig = strConfig + "<PropertyName2>Batch Size</PropertyName2>";
strConfig = strConfig + "<PropertySource2>" + sBatchSize + "</PropertySource2>";
strConfig = strConfig + "<PropertyName3>Invoice Number</PropertyName3>";
strConfig = strConfig + "<PropertySource3>" + sInvoice + "</PropertySource3>";
strConfig = strConfig + "</ConfigPropertiesXml>";
Msg(WSS.ConfigPropertiesXml) = strConfig;

 

La tercera opción es utilizar una combinación de ambos escenarios para definir las columnas: definir una parte de las columas en la configuración del puerto y otra parte en la orquestación.  Se debe tener cuidado de no especificar una misma columna en ambos lugares para evitar conflictos, en el siguiente ejemplo se adiciona una columna al puerto estático de envío configurado en la primera opción.

strConfig = "<ConfigPropertiesXml>";
strConfig = strConfig + "<PropertyName4>Source</PropertyName4>";
strConfig = strConfig + "<PropertySource4>" + sSource + "</PropertySource4>";
strConfig = strConfig + "</ConfigPropertiesXml>";
Msg(WSS.ConfigPropertiesXml) = strConfig;

 

Esta última opción es muy util cuando una parte las columnas son relativamente estáticas, mientras que otra parte son dinámicas y bien sea las columnas mismas o sus valores solo pueden ser calculados en tiempo de ejecución.

En la siguiente dirección pueden encontrar todos los posters que Microsoft ha generado para BizTalk 2006 R2 explicando todas sus características.

http://www.microsoft.com/biztalk/techinfo/guides.mspx 


También existe un poster acerca de la arquitectura en BizTalk 2006 y puede ser descargado aquí

El proceso de depuración de la base de datos de tracking "DTA" en BizTalk 2004 o BizTalk 2004 SP1 puede tardar horas o tal vez días, depende de la cantidad de información en la BD, debido a la lógica del procedimiento dtasp_PruneTrackingdatabase().  Este inconveniente no sucede en BizTalk 2006 y BizTalk 2004 SP2 por que se hicieron unas correcciones a estos procesos de depuración de las bases de datos. 

Sin embargo, parte del proceso de instalación de BizTalk 2004 SP2 es limpiar la BD de tracking por lo tanto si esta tiene mucha información dicho proceso podra tardarse mas horas de lo previsto ya que utiliza este procedimiento.

Para evitar este inconveniente, ES NECESARIO instalar el Hotfix 894253 antes de instalar BizTalk 2004 SP2.  Este hotfix contiene un script que elimina toda la información relacionada exclusivamente a las instancias completadas de la BD de tracking, con la única salvedad que todos los registros serán borrados sin tener en cuenta su fecha de almacenamiento.

De igual forma, este hotfix puede aplicarse a BizTalk 2004 o BizTalk 2004 SP1 para depurar información de la BD y evitar su constante crecimiento.

Los tipos de aceleradores [WMISEARCHER] y [WMI] permiten consultar objetos de wmi en forma mas sencilla desde PowerShell.  Basicamente estos tipos complementan con una sintaxis mas compacta la funcionalidad del cmdlet Get-WmiObject.

[WMI] es utilizado para obtener una instancia especifica de un tipo de clase:

$hosts = [WMI]'root\MicrosoftBizTalkServer:MSBTS_HostInstance.Name="Microsoft BizTalk Server BizTalkServerIsolatedHost SERVERNAME"'
$hosts | select HostName,Logon,Name | format-list

[WMISEARCHER] es utilizado para obtener instancias de una clase en WMI utilizando una consulta WQL:

$hosts = [WMISEARCHER] "select * from MSBTS_HostInstance"
$hosts.scope = "root\MicrosoftBizTalkServer"
$hosts.Get()

En el caso del [WMISEARCHER] es necesario la utilizacion de la propiedad .scope para poder acceder a las clases que no esten en el namespace por defecto de WMI antes de intentar obtener el resultado de la consulta.

En ocasiones es necesario utilizar BizTalk Server para un escenario de mensajería el cual debe consultar información a una aplicación externa y luego enviar ésta a otra aplicación externa sin necesidad de aplicar alguna logica de negocio durante su proceso. 

En ocasiones se utilizan orquestaciones en este tipo de escenarios lo cual algunas veces puede resultar innecesario.  Para ilustrar esta situación se puede tomar el ejemplo HTTPSolicitResponse que viene en SDK de BizTalk Server 2004/2006/2006r2.  HTTPSolicitResponse muestra una forma de cómo usar BizTalk Server para consultar un servicio HTTP y luego enviar la respuesta el FileSystem.  Los artefactos usados en esta solución son:

  • Un Receive Port llamado HTTPSolicitResponseReceivePort que recibe la información desde el FileSystem
  • Una orquestacion que procesa la información
  • Un Send Port llamado HTTPSolicitResponseTwoWayPort que envía hace la petición al servicio HTTP
  • Un Send Port llamado HTTPSolicitResponseSendPort que envía el resultado al FileSystem

Sin embargo, en su ejecución esta solución utiliza más recursos de los estrictamente necesarios, debido aque se usa una orquestacion como enrutadora sin procesar ningun tipo de proceso de negocio real tal como puede observar en la siguiente figura.

image

De acuerdo a la arquitectura de BizTalk Server (ver figura) todos los mensajes deben pasar por el MessageBox para poder ser instanciados por las orquestaciones o puertos de envio.

image

 

Mejorando la solución

Para mejorar el performance de la solución podría eliminarse la orquestación lo que permitiría reducir su ejecución a los siguientes pasos:

1. HTTPSolicitResponseReceivePort envía el mensaje a MessageBox

2. HTTPSolicitResponseTwoWayPort recibe el mensaje desde MessageBox y envía la solicitud HTTP, una vez recibe la respuesta vuelve a enviar el mensaje a MessageBox

3. HTTPSolicitResponseSendPort recibe el mensaje desde la MessageBox y lo envía al FileSystem

 

De igual forma, al eliminar la orquestación el gráfico de arquitectura también sería modificado así.

image

El nuevo escenario presenta estas ventajas:

1. Se evita una ejecución innecesaria de la orquestación

2. Menor utilizacion del MessageBox, lo que significa menor consumo de recursos

 

Para lograr este nuevo escenario se debe configurar los puertos de salida (Send Ports) para que sean instanciados una vez el mensaje el publicado en el MessageBox.  A continuación se muestra la forma de como configurar la nueva solución:

1. Poner en estado Unenlist la orquestación MultiplyTwoIntegers

2. Editar las propiedades del Send Port llamado HttpSolicitResponseTwoWayPort y establecer este filtro:

BTS.ReceivePortName == HttpSolicitResponseReceivePort

3. Editar las propiedades del Send Port llamado HttpSolicitResponseSendPort y establecer este filtro:

BTS.SPName == HttpSolicitResponseTwoWayPort

4. Probar el nuevo escenario copiando el archivo en la carpeta de recepción

 

También se puede hacer undeploy del assembly HttpSolicitResponse.dll y probar nuevamente.  Sin embargo, al realizar este cambio también se debe cambiar los pipelines utilizados en los puertos de la siguiente forma:

1.  Los pipelines XmlReceive por PassThruReceive en el Receive Location HttpSolicitResponseReceiveLocation y en el Send Port HttpSolicitResponseTwoWayPort

2. Los pipelines XmlTransmit por PassThruTransmit en los Send Ports HttpSolicitResponseTwoWayPort y HttpSolicitResponseSendPort

El anterior cambio sería necesario ya que los pipelines Xml* generarían un error al procesar los mensajes intentando obtener su MessageType desde la BizTalkMgmtDb.

 

Conclusión

Lo anterior indica que NO se deberia utilizar orquestaciones que solo sirvan como reenrutadoras de la informacion y NO ejecuten alguna logica de negocio real en un escenario de mensajeria.

De igual forma estos escenario de mensajeria se pueden utilizar para consultar información a SQL Server con el adaptador de SQL, consultar un Servicio Web usando el adaptador de SOAP (ver ejemplo Consumming Web Services with Messaging-Only Scenario), u otro escenario de estas características.

Una de las técnicas utilizadas para definir mensajes al desarrollar orquestaciones es usar objetos System.Xml.XmlDocument.  Sin embargo, es necesario tener cuidado al momento de utilizar el mismo objeto para definir mas de un mensaje usando un sólo "Construction Shape" ya que los mensajes pueden no almacenarse en la base de datos con la información esperada.

El siguiente escenario (ver figura) pretende explicar con más detalle lo comentado.

image

En la figura se observa como la orquestación construye dos mensajes: Msg2 y Msg3, usando el mismo "Construction Shape" y para ambos mensajes usa el mismo objeto xmlDoc de tipo System.Xml.XmlDocument.  Asi, en el primer Message Assigment Shape el siguiente codigo define el Msg2:

// carga xml y asigna el Msg2
xmlDoc.LoadXml("<Root><Field>Field_2</Field></Root>");
Msg2 = xml;

Y en el segundo Message Assigment Shape este codigo define el Msg3:

// carga xml y asigna el Msg3
xmlDoc.LoadXml("<Root><Field>Field_3</Field></Root>");
Msg3 = xml;

En teoria el resultado deberia ser dos archivos diferentes, sin embargo el resultado al ejecutarse la orquestación no es el esperado ya que ambos archivos contienen la misma informacion.

image

Este inconveniente se debe a dos razones:

  1. El mensaje de BizTalk guarda una referencia al objeto XmlDocument asignado.
  2. El objeto XmlDocument fue modificado en el mismo Construction Shape por lo que no fue posible hacer persistente el mensaje.

Por lo tanto, el objeto xml que se utilizo para definir el Msg2 fue modificado para construir el Msg3 antes de que el mensaje Msg2 se hiciese persistente.  Esto ocasiono que el contenido de ambos mensajes en la base de datos sea el mismo.

Esta característica esta presente en las versiones de biztalk 2004/2006/2006r2.

Una de las principales características al crear archivos .MSI para instalar aplicaciones de BizTalk Server 2006 en otros ambientes, es poder adicionar archivos de configuración (binding files) y especificar en cual ambiente van a ser utilizados.

Esta funcionalidad permite generar un solo instalador que sirve para los diferentes ambientes como desarrollo, precalidad, calidad, QA, y producccion, entre otros (depende de las politicas de la empresa). 

Este proceso es sencillo, basta con adicionar un archivo de configuración como recurso desde la consola administrativa y especificar el ambiente (target) en el cual se quiere ejecutar.

image

De esta forma se pueden tener todos los archivos de configuración necesarios para los diferentes ambientes en un solo instalador.

image

Por último, al momento de importar el archivo simplemente se debe seleccionar el ambiente correcto para aplicar la configuración deseada.

image

Sin embargo, cuando se importa un archivo .MSI la configuración se aplica de acuerdo al siguiente orden:

  1. Se crea la configuración generada automáticamente cuando se exporto el archivo .MSI.  Esto si la aplicacion tenía puertos de envío, recepción, u otros.
  2. Aplica los archivos de configuración que se adicionaron como recursos pero a los cuales no se especificó un ambiente (target).
  3. Aplica los archivos de configuración de acuerdo al ambiente seleccionado.

Este orden de ejecución puede causar algunos inconvenientes en la instalación de la aplicación ya que se puede crear configuración como puertos de envios u otros en ambientes no deseasdos, p. ej. un ambiente de producción.  Por lo tanto se recomienda tener en cuenta:

  • Cuando se exporte el archivo .MSI, asegurarse de no seleccionar la opcion Binding que se presenta en la ventana Select Resources.  Esta opción indica que no se genere la configuración por defecto de la aplicación.

image

  • Especificar siempre un ambiente (target) a los archivos de configuración asociados como recursos, de esta forma la configuración siempre sera aplicada de acuerdo al ambiente seleccionado. 

De esta forma no se tendran inconvenientes en el momento de la realizar los despliegues de las aplicacion de BizTalk Server 2006.

Autor: Carlos Medina
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningun derecho

Existen dos formas de consultar instancias de servicios en BizTalk Server 2006, utilizando WMI o utilizando Microsoft.Biztalk.Operations.

WMI

Usando WQL se puede realizar una consulta a la clase MSBTS_ServiceInstance y retornar todas las instancias de servicio con sus respectivos valores dados por el proveedor para WMI en BizTalk.  Esta opción es válida en BizTalk 2004 y BizTalk 2006.

using System.Management;
......


ManagementObjectSearcher searcher = 
    new ManagementObjectSearcher("root\\MicrosoftBizTalkServer", 
    "SELECT * FROM MSBTS_ServiceInstance"); 

foreach (ManagementObject queryObj in searcher.Get())
{
    Console.WriteLine("-----------------------------------");
    Console.WriteLine("MSBTS_ServiceInstance instance");
    Console.WriteLine("-----------------------------------");
    Console.WriteLine("ActivationTime: {0}", queryObj["ActivationTime"]);
    Console.WriteLine("ErrorCategory: {0}", queryObj["ErrorCategory"]);
    Console.WriteLine("ErrorDescription: {0}", queryObj["ErrorDescription"]);
    Console.WriteLine("ErrorId: {0}", queryObj["ErrorId"]);
    Console.WriteLine("HostName: {0}", queryObj["HostName"]);
    Console.WriteLine("InstanceID: {0}", queryObj["InstanceID"]);
    Console.WriteLine("MgmtDbNameOverride: {0}", queryObj["MgmtDbNameOverride"]);
    Console.WriteLine("MgmtDbServerOverride: {0}", queryObj["MgmtDbServerOverride"]);
    Console.WriteLine("PendingOperation: {0}", queryObj["PendingOperation"]);
    Console.WriteLine("PendingOperationTime: {0}", queryObj["PendingOperationTime"]);
    Console.WriteLine("ServiceClass: {0}", queryObj["ServiceClass"]);
    Console.WriteLine("ServiceClassId: {0}", queryObj["ServiceClassId"]);
    Console.WriteLine("ServiceName: {0}", queryObj["ServiceName"]);
    Console.WriteLine("ServiceStatus: {0}", queryObj["ServiceStatus"]);
    Console.WriteLine("ServiceTypeId: {0}", queryObj["ServiceTypeId"]);
    Console.WriteLine("Status: {0}", queryObj["Status"]);
    Console.WriteLine("SuspendTime: {0}", queryObj["SuspendTime"]);
}

Microsoft.BizTalk.Operations

Otra forma es utilizar Microsoft.Biztalk.Operations, esta librería viene en BizTalk 2006 y permite consultar instancias de servicios y/o mensajes a la base de datos MessageBox o a la base de datos de traceo (Tracking).  A diferencia de los resultados retornados en WMI, M.B.O. devuelve una coleccion de objetos que se mapean a difernetes clases de acuerdo al tipo de instancia de servicio tal como se muestra en el código de ejemplo.

De igual forma, M.B.O. tiene información que WMI no retorna como el nombre de la aplicación, si esta en breakpoint, y si el puerto de envío es el primario, entre otras.

using Microsoft.BizTalk.Operations;
......

BizTalkOperations ops = new BizTalkOperations();
IEnumerable enumb = ops.GetServiceInstances();
IEnumerator enumt = enumb.GetEnumerator();

while (enumt.MoveNext())
{
    object inst = enumt.Current;

    if (inst is Instance)
    {
        Instance instance = inst as Instance;
        Console.WriteLine(instance.Class);
        Console.WriteLine(instance.CreationTime);
        Console.WriteLine(instance.ErrorDescription);
        Console.WriteLine(instance.HostName);
        Console.WriteLine(instance.ID);
        Console.WriteLine(instance.InstanceStatus);
        Console.WriteLine(instance.ServiceType);
        Console.WriteLine(instance.ServiceTypeID);
    }

    if (inst is MessageBoxServiceInstance)
    {
        MessageBoxServiceInstance msginst = inst as MessageBoxServiceInstance;
        Console.WriteLine(msginst.Adapter);
        Console.WriteLine(msginst.Application);
        Console.WriteLine(msginst.CurrentProcessingServer);
        Console.WriteLine(msginst.ErrorCategory);
        Console.WriteLine(msginst.ErrorCode);
        Console.WriteLine(msginst.ErrorProcessingServer);
        Console.WriteLine(msginst.MessageBox);
        Console.WriteLine(msginst.PendingOperation);
        Console.WriteLine(msginst.PendingOperationSubmitTime);
        Console.WriteLine(msginst.SuspendTime);
        Console.WriteLine(msginst.URI);
    }

    if (inst is SendPortInstance)
    {
        SendPortInstance spinst = inst as SendPortInstance;
        Console.WriteLine(spinst.HasServiceWindow());
        Console.WriteLine(spinst.IsPrimaryTransport());
        Console.WriteLine(spinst.Priority);
        Console.Write(spinst.ServiceWindowEnd);
        Console.Write(spinst.ServiceWindowStart);
    }

    if (inst is TrackedServiceInstance)
    {
        TrackedServiceInstance tinst = inst as TrackedServiceInstance;
        Console.WriteLine(tinst.EndTime);
        Console.WriteLine(tinst.ExitCode);
        Console.WriteLine(tinst.TrackingDb);
    }

    if (inst is OrchestrationInstance)
    {
        OrchestrationInstance oinst = inst as OrchestrationInstance;
        Console.WriteLine(oinst.InBreakpoint);
        Console.WriteLine(oinst.UserState);
    }

    if (inst is MSMQtInstance)
    {
        MSMQtInstance minst = inst as MSMQtInstance;
        Console.WriteLine(minst.InboundUserState);
        Console.WriteLine(minst.MSMQtDirection);
        Console.WriteLine(minst.OutboundUserState);
    }
}

 

Autor: Carlos Medina
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningun derecho

BizTalk Server a través del Business Rule Engine (BRE) ofrece la posibilidad de almacenar las reglas de negocio (BR) implementadas en archivos xml o en bases de datos para su posterior invocación y ejecución.  Cada almacenamiento ofrece sus ventajas y desventajas, y adicional su invocación difiere en cada uno.

Archivos XML

Una BR se puede almacenar e invocar desde un archivo plano usando la clase FileRuleStore.

void SaveToFile()
{
    RuleStore ruleStore = new FileRuleStore("filename");
    ruleStore.Save(new RuleSet("rulesetname"));
}

void LoadFromFile()
{
    RuleStore ruleStore = new FileRuleStore("filename");
    RuleSetInfoCollection rsInfo = ruleStore.GetRuleSets("rulesetname", RuleStore.Filter.Latest);
    RuleSet newRS = ruleStore.GetRuleSet(rsInfo[0]);
}

Este almacenamiento ofrece las siguientes ventajas:

  • No es necesario tener una base de datos (como SQL Server) para su almacenamiento y ejecución.
  • El instanciamiento de la BR es mas rápida ya que evita el acceso a la base de datos.
  • La BR puede ser modificada con un editor como Bloc de Notas (notepad) y no es necesaria su publicación (publish) y despliegue (deploy) posterior.

Las desventajas son:

  • Estas BR no pueden ser invocadas desde un orquestación con el Call Rules Shape, sólo desde .net assemblies utilizando la clase FileRuleStore.
  • Si una BR va a ser accedida por varias aplicaciones se debe copiar el archivo en una ruta compartida o crear una copia en cada aplicación.
  • No se puede editar con el Business Rule Composer.

Base de datos

Una BR puede ser almacenada e invocada desde una base de datos usando las clases SqlRuleStore o OleDbRuleStore

using Microsoft.BizTalk.RuleEngineExtensions;

static void DeployRuleSet(RuleSet ruleset)
{
    RuleSetDeploymentDriver dd = new RuleSetDeploymentDriver();
    SqlRuleStore sqlrs;
    sqlrs = (SqlRuleStore) dd.GetRuleStore();

    sqlrs.Add(ruleset, true);
    dd.Deploy(new RuleSetInfo(ruleset.Name, 
            ruleset.CurrentVersion.MajorRevision, ruleset.CurrentVersion.MinorRevision));
}

static void GetRuleStore(string rulesetname)
{
    RuleSetDeploymentDriver dd = new RuleSetDeploymentDriver();
    SqlRuleStore sqlrs = (SqlRuleStore) dd.GetRuleStore();

    RuleSetInfoCollection rss = new RuleSetInfoCollection();
    rss = sqlrs.GetRuleSets(rulesetname, RuleStore.Filter.Latest);
}

Las ventajas de utilizar una base de datos se enumeran en:

  • Las BR quedan almacenadas en forma centralizada, por lo tanto las aplicaciones que la consuman tendran siempre un repositorio único
  • Se puede utilizar el Business Rule Composer para administrar las BR, publicarlas (publish) o desplegarlas (deploy).
  • La BR puede ser invocada desde un .net assembly utilizando las clases provitas por el framework de BRE.
  • Las BR pueden ser invocadas desde orquestaciones usando Call Rules Shapes.

Las desventajas son:

  • El instanciamiento inicial de la BR puede ser lenta dependiendo de la conexion a la base de datos
  • Se debe tener una base de datos para el almacenamiento de las BR
  • La administracion y modificaciones a las BR tienen que hacerse por medio de un editor de BR, ejemplo el Business Rule Composer.

 

En ambos casos se puede exportar facilmente una BR de un archivo xml a la base de datos y viceversa, para ello se puede utilizar el framework de BRE o el Business Rule Engine Deployment Wizard que provee BizTalk Server.

 

Autor: Carlos Medina
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningun derecho

Microsoft ofrece 3 clínicas para los desarrolladores y el público en general que aún no han incursionado el potencial de las nuevas tecnologías WCF, WPF y WF que vienen con a partir del framework 3.0 de .NET.  Estas clínicas corresponden a:

Clinic 5135: Introduction to Developing with Windows Presentation Foundation and Visual Studio 2005

Clinic 5136: Introduction to Developing with Windows Workflow foundation and Visual Studio 2005

Clinic 5137: Introduction to Developing with Windows Communication Foundation and Visual Studio 2005

Todos los detalles del curso y subscripción al mismo la puedes encontrar en Collection 5134: Developing Rich Experiences with Microsoft .Net Framework 3.0 and Visual Studio 2005

El equipo de BizTalk Server ha publicado 3 posters que tratan sobre las caracteristicas BizTalk Server 2006, y que pueden ser utilizados como ayudas en presentaciones del producto. 

Estos pueden ser descargados desde  Biztalk Server 2006 Capabilities,  Biztalk Server 2006 Runtime Architecture y  Biztalk Server 2006 Legacy Modernization with Host Integration Server.

 

Autor: Carlos Medina
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningun derecho

Esta nueva versión de ContextAccessor resume en un componente dos functoids que permiten obtener el valor de propiedades de contexto, estos son:

  • Orchestration Context Accessor: functoid utilizado en un mapa desde una orquestacion.
  • RcvPort Context Accessor: functoid utilizado en un mapa desde un puerto de recepción

Asi mismo, este componente contiene un Custom Pipeline Component necesario para la ejecucionde RcvPort Context Accessor functoid.

  • ContextAccessorProvider: utilizado para promover el contexto desde un pipeline hasta el mapa.

Estos functoids y el custom pipeline component pueden ser visualizados en el barra de herramientas (ver figura)

Orchestration Context Accessor

Este functoid se utiliza en mapas desde una orquestación y recibe 4 parámetros:

  • Primer parametro: parámetro obligatorio que contiene el nombre del mensaje en la orquestación que contiene la propiedad de contexto.
  • Segundo parámetro: parámetro obligatorio que contiene el nombre de la propiedad de contexto.
  • Tercer parámetro: parámetro obligatorio que contiene el namespace perteneciente a la propiedad de contexto.
  • Cuarto parámetro: parámetro opcional que será retornado cuando la propiedad especificada no existe en el mensaje.

 

RcvPort Context Accessor

Este functoid se utiliza en mapas desde un puerto de recepción (Receive Port), y recibe 3 parámetros:

  • Primer parámetro: parámetro obligatorio que contiene el nombre de la propiedad de contexto.
  • Segundo parámetro: parámetro obligatorio que contiene el namespace perteneciente a la propiedad de contexto.
  • Tercer parámetro: parámetro opcional que será retornado cuando la propiedad especificada no exista en el contexto.

ContextAccessorProvider

Este componente debe ser utilizado desde un Custom Pipeline (ver figura) cuando se desea utilizar el RcvPort Context Accessor.  El ContextAccessorProvider tiene la funcionalidad de promover el contexto utilizado en el pipeline hasta en el mapa.

El assembly que representa estos componentes y el código fuente de éste puede ser descargado desde http://www.codeplex.com/ContextAccessor

 

Autor: Carlos Medina
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningun derecho

Sintoma

Tu recibes el siguiente error al tratar de compilar proyectos de BizTalk Server 2006 que contienen mapas:

Error: Build failed. Compiler for file type '*.btm' failed. Unable to load wrapper:C:\Program Files\Microsoft BizTalk Server 2006\Developer Tools\Mapper Extensions\Microsoft.BizTalk.Security.SSPI.dll.

Solución

El assembly Microsoft.BizTalk.Security.SSPI.dll está por defecto registrado en el GAC y el compilador de BizTalk Server 2006 lo carga desde allí, por lo tanto es necesario eliminar la copia de éste assembly de la carpeta %install_bts%\Developer Tools\Mapper Extensions\.

 

Autor: Carlos Medina
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningun derecho

Microsoft ha realizado una alianza con www.laborum.com para crear una bolsa de trabajo para la Región Andina (esto es Colombia, Ecuador, Perú y Venezuela) dirigida a aquellas personas IT Pros que están en busca de empleo o que quieren mejorar el actual.

Pueden encontrar más información en la siguiente nota de Guillermo Taylor.

 

Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningun derecho

La propiedad IncludeExceptionDetailInFaults es utilizada para habilitar a los servicios de WCF el envio de informacion detallada cuando una excepcion ocurre en objetos SOAP fault hacia el cliente.  El propósito de esta acción, es brindarle al cliente más información en pruebas de la aplicación. 

Por defecto, el valor de esta propiedad es false por motivos de seguridad.  Sin embargo existen varias formas de cambiar este valor las cuales se ejemplarizan a continuación:  

Utilizando .config 

Esta es la forma más utilizada por su comodidad ya que basta con editar el archivo de configuración del servicio WCF y especificar al atributo includeExceptionDetailInFaults el valor true

Al hacer esta operación, todos los endpoints relacionados al servicio enviarán información detallada de errores en cualquier momento.

<system.serviceModel>
  <services>
    <service name="BizTalkLATAM.WCF.DebugService"
             behaviorConfiguration="DebugServiceConfiguration">
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="DebugServiceConfiguration">
        <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

Utilizando código 

También es posible habilitar esta propiedad utilizando código, para esto existen dos formas.  La primera es especificando la propiedad IncludeExceptionDetailInFaults con el valor de true en el atributo ServiceBehaviorAttribute aplicado a la clase que representa el servicio. 

[ServiceContract(Namespace="http://wcf.biztalklatam.com/debug/")]
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class DebugService
{ }

La segunda forma es estableciendo el valor de la propiedad IncludeExceptionDetailInFaults en true antes de invocar el metodo Open() del servicio, esto sin necesidad de especificar el atributo ServiceBehaviorAttribute a la clase que representa el servicio. 

[ServiceContract(Namespace="http://wcf.biztalklatam.com/debug/")] 
public class DebugService { }
using (ServiceHost host = new ServiceHost(typeof(DebugService)))
{
    ServiceDescription svcDesc = host.Description.Behaviors;
    ServiceDebugBehavior svcDebug = svcDesc.Behaviors.Find<ServiceDebugBehavior>();
    svcDebug.IncludeExceptionDetailInFaults = true;
    host.Open();
}

Habilitando parcialmente la propiedad

Las técnicas anteriormente vistas habilitan la propiedad  IncludeExceptionDetailInFaults para todos los endpoints de un servicio, pero cómo hacer si solo un endpoint se desea habilitar para ello?

En el siguiente ejemplo se utilizan dos endpoints: debug1 y debug2, de acuerdo al atributo bindingName.  Y se requiere que el endpoint debug1 envie información detallada en el momento de una excepción pero debug2 no.

<system.serviceModel>
  <services>
    <service name="BizTalkLATAM.WCF.DebugService"
             behaviorConfiguration="DebugServiceConfiguration">
      <endpoint address="net.tcp://localhost:8009/wcf/debugep1"
                binding="netTcpBinding"
                bindingName="debug1"
                bindingNamespace="http://wcf.biztalklatam.com/binding/"
                contract="BizTalkLATAM.WCF.DebugService" />
      <endpoint address="net.tcp://localhost:8009/wcf/debugep2"
                binding="netTcpBinding"
                bindingName="debug2"
                bindingNamespace="http://wcf.biztalklatam.com/binding/"
                contract="BizTalkLATAM.WCF.DebugService" />
    </service>
    <behaviors>
   
<serviceBehaviors>
    
<behavior name="DebugServiceConfiguration">
     
<serviceDebug includeExceptionDetailInFaults="false"/>
    
</behavior>
   
</serviceBehaviors>
 
</behaviors>
  </services>
</system.serviceModel>

Luego de definir el archivo de configuración, se debe cambiar el valor de la propiedad IncludeExceptionDetailInFaults a true al endpoint debug1.  Para esto es necesario buscar en la colección ChannelDispatchers del servicio WCF el ChannelDispatcher que representa el endpoint debug1, esto se logra fácilmente usando la propiedad ChannelDispatcher.BindingName.  Una vez localizado el endpoint, se cambia la propiedad IncludeExceptionDetailInFaults a true.

Ya que modificar la propiedad IncludeExceptionDetailInFaults en un objeto tipo ChannelDispatcher solo se puede hacer cuando el objeto se encuenta en un estado Created, es necesario implementar una nueva clase que derive de la interfaz IServiceBehavior e implementar el código correspondiente a la modificación de la propiedad en el método ApplyDispatchBehavior.

Posteriormente se establece el nuevo atributo a la clase que representa el servicio WCF.

[ServiceContract(Namespace = "http://wcf.biztalklatam.com/debug/")]
[CustomDebugBehavior]
public class DebugService
{ }

public class CustomDebugBehaviorAttribute : Attribute, IServiceBehavior
{
    #region IServiceBehavior Members
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, 
        System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, 
        System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
        // sin implementar
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers)
            if (cd.BindingName.Equals("http://wcf.biztalklatam.com/binding/:debug1"))
                cd.IncludeExceptionDetailInFaults = true;
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        // sin implementar
    }
    #endregion
}

Por último se inicia el servicio WCF en forma normal: 

using (ServiceHost host = new ServiceHost(typeof(DebugService))) {
 host.Open();
 ...
}

 

La propiedad IncludeExceptionDetailInFaults nos ayuda en pruebas a encontrar mas información acerca de errores, pero se aconseja deshabilitarla para producción.  Sin embargo, es posible utilizar algun tipo de habilitación parcial de un endpoint para dejar habilitado en producción y en caso de error poder obtener mas información.

 

Autor: Carlos Medina
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningun derecho

0 Comments
Filed under:
More Posts Next page »
 
Page view tracker