MainMind

True & racing de norte a sur


Sintaxis en servicios WCF asíncronos

A la hora de generar servicios escalables que aprovechen el procesamiento en paralelo algunos detalles sintácticos deben realizarse literalmente. La nomenclatura puede perderse por el camino generando errores en el momento de ejecutar los servicios:

Your begin method must take an AsyncCallback and an object as the last two arguments and return an IAsyncResult.

Signatura no válida del método Begin asincrónico para el método miFuncionAsyncIniciar en el tipo de XXXX. El método Begin debe tomar AsyncCallback y un objeto como los dos últimos argumentos y devolver IAsyncResult

 

El procedimiento debe tener asociadas la tareas iniciando con el nombre Begin con los dos últimos parámetros AsynCallBack y object:

 

public interface IEjemplo
{

    [OperationContractAttribute]
    string MiFuncion(string mensaje, int otroParametro);

    [OperationContractAttribute(AsyncPattern = true)]
    IAsyncResult BeginMiFuncion(string mensaje, int otroParametro, AsyncCallback callback, object asyncState);

    //No se especifica OperationContractAttribute para el método de finalización.
    string EndMiFuncion(IAsyncResult result);

}

La documentación esta clara pero la traducción puede generar confusión con un sencillo erros de sintaxis obligatoria. 

 

How to: Implement an Asynchronous Service Operation

Sessions, Instancing, and Concurrency

 

Ejemplo completo de una excepción tipo:

 

System.InvalidOperationException: Signatura no válida del método Begin asincrónico para el método UnirAsyncIniciar en el tipo de ServiceContract XXXXXX. El método Begin debe tomar AsyncCallback y un objeto como los dos últimos argumentos y devolver IAsyncResult.
   en System.ServiceModel.Description.ServiceReflector.IsBegin(OperationContractAttribute opSettings, MethodInfo method)
   en System.ServiceModel.Description.TypeLoader.CreateOperationDescription(ContractDescription contractDescription, MethodInfo methodInfo, MessageDirection direction, ContractReflectionInfo reflectionInfo, ContractDescription declaringContract)
   en System.ServiceModel.Description.TypeLoader.CreateOperationDescriptions(ContractDescription contractDescription, ContractReflectionInfo reflectionInfo, Type contractToGetMethodsFrom, ContractDescription declaringContract, MessageDirection direction)
   en System.ServiceModel.Description.TypeLoader.CreateContractDescription(ServiceContractAttribute contractAttr, Type contractType, Type serviceType, ContractReflectionInfo& reflectionInfo, Object serviceImplementation)
   en System.ServiceModel.Description.TypeLoader.LoadContractDescriptionHelper(Type contractType, Type serviceType, Object serviceImplementation)
   en System.ServiceModel.Description.ContractDescription.GetContract(Type contractType, Type serviceType)
   en System.ServiceModel.ServiceHost.CreateDescription(IDictionary`2& implementedContracts)
   en System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses)
   en System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses)
   en Microsoft.Tools.SvcHost.ServiceHostHelper.CreateServiceHost(Type type, ServiceKind kind)
   en Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)

 

 

 

Actualizar TFS 2015 Update 4 en sistemas no ingleses

En ocasiones actualizar las versiones de Team Foundation Server en instalaciones locales necesita de una preparación adicional, si no hubo planificación anterior o las condiciones de infraestructuras no son las idóneas. Entre ellas, existe la limitación de idiomas, en las que debemos de tener en cuenta si nuestros servidores de base de datos SQL Server no están en inglés, debemos tener instalado el paquete de idioma correspondiente, por ejemplo Inglés y Español en el sistema donde reside TFS.

Al intentar instalar nos aparecerá el mensaje siguiente:

En el registro de la instalación aparece:

[0C18:0CD8][2014-00-00T13:33:25]i000: MUX:  Stop Block: Dev14_LanguageInstall : La versión de Team Foundation Server instalada actualmente está en otro idioma. Solo puede haber un idioma de Team Foundation Server instalado.

No se trata solo de añadirlo al sistema operativo, deben estar instalados los paquetes de idiomas (Control Panel -> Clock, Language and Region -> Language, dentro de cada idioma desde Options pulsamos sobre Download and install language pack

 

 Una vez instalado el idioma (si no lo estaba) debe ser el principal del sistema operativo, reiniciar el equipo y ya será posible instalar la actualización. Deben coincidir Formato, Ubicación e Idioma

Debug Linq SQL

En ocasiones podemos encontrar sentencias complejas o sin errores aparentes, otra forma de intentar buscar soluciones es mostrar la sentencial SQL generada por Entity Framework. Tan solo debemos habilitar el log, mostrandolo en en panel Output de nuestro Visual Studio por ejemplo:

 

                using (ModeloEntities entidad = new ModeloEntities ())
                {

                    entidad.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
                    var resultado = (nuestraConsultaLINQ)

                }

 

Errores JavaScript en entornos de prueba locales: Browser Link

En ocasiones es posible obtener errores en entornos de desarrollo, pero una vez en producción no suceden; este puede ser uno de los motivos dependiendo del caso. A partir de la versión Visual Studio 2013 se introdujo una características nueva: Browser Link que permite interceptar las llamadas AJAX mediante SignalR estableciendo una canal intermedio entre Visual Studio y el navegador.

Para tal función se inserta automáticamente código JavaScript en la página generada que puede llegar a interferir, por ejemplo con Bootstrap o controles de terceros, generando el error en tiempo de ejecución del tipo:

La prueba rápida es deshabilitar esta característica desde el propio entorno VS:

En entornos de producción con la compilación fuera del modo debug no se realiza la carga de esta característica, solo sobre localhost.

<system.web>
  <compilation debug="false" targetFramework="4.5" />
</system.web>

 

Adaptar nombre de servicio WCF/SVC según cabecera URL de acceso

En ocasiones un servicio web puede ser accedido de diferentes direcciones, configuración de redes, balanceos de carga... es posible especificar en un servicio WCF para que adopte la dirección de cabecera de forma automática en pocas líneas para los metadatos:

    <behaviors>
      <serviceBehaviors>
        <behavior name="customBehaviour">
          <useRequestHeadersForMetadataAddress>
            <defaultPorts>
              <add scheme="https" port="443" />
            </defaultPorts>
          </useRequestHeadersForMetadataAddress>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

Para realizar manualmente la localización externa:

<serviceMetadata httpGetEnabled="true"  externalMetadataLocation="https://ws.misitio.com/servicio.svc?wsdl"/>