Gestión de modelos con “bundle”

Acabo de descubrir un sistema para gestión de todo tipo de código y dependencias, que no utilizaba para las paginas web. Se llama Webpack

Este bundle https://webpack.js.org permite tener el código mas ordenado, optimizar ancho de banda y gestionar bien las dependencias. Pero el futuro ya esta llegando con ECMAScript, que ya esta soportado por navegadores, así que solo es una herramienta buena pero supongo que dentro de un tiempo ya estará obsoleta.

Porque se desaparecen bindings en XAML C#

Basicamente los binding’s desaparecen porque alguien los borra de alguna manera. Y como programadores normalmente no lo hacen, piensan que los binding’s de las propiedades siempre deben funcionar y siempre estan presentes, lo que no es verdad. Y hay un caso bastante facil de ver, pero complicado de entender que esta pasando.

Yo me encontre con la situación que despues de ver un CheckBox marcado gracias al binding, luego se queda marcado siempre y no me cambia el valor aún que se cambia el Context. Si el binding estaria funcionando, todo seria perfecto, pero no funcionaba. Al principio he pensado que problema esta con Mode=TwoWay/OneWay/etc, luego con posible problema de “UpdateTrigger” de la propiedad mostrada y en parte es correcto, pero el Binding en si, dejaba de existir asociado a propiedad “IsChecked”.

Para ver si existe binding podeis utilizar el codigo:

BindingExpression be = cbIsClient.GetBindingExpression(ToggleButton.IsCheckedProperty);

Si “be” es igual a “null”, no existe “binding” en esta propiedad.
Asi que si os deja de funcionar, en diferentes partes de codigo podeis ir detectando en que momento acaba desapareciendo. Gracias a esta investigación bastante manual vi un error mio que yo nunca consideraba que podria ser un error.

Imaginar el caso que tenemos un objeto “Coche” con una propiedad “Cliente”, la cual a su vez es un objeto. En pantalla con XAML dibujamos un CheckBox que tiene que estar marcado cuando “Coche.Cliente != null” y desmarcado cuando propiedad es nula. Se puede utilizar “Converter” personalizado para solventar este problema, pero necesitamos que salta el trigger si se cambia la propiedad “Coche.Cliente”. Si no lo podemos hacer de una forma facil por codigo, al no tener acceso a la propiedad “Cliente” (por ejemplo es de una libreria externa), yo pense que podria hacer simplemente:

cbIsClient.IsChecked = Coche.Cliente != null;

Y cuando pasa por esta parte de codigo se marca o se desmarca correctamente. El problema lo vi luego, al cambiar de un objeto “Coche” a otro de la lista. Vi que por si solo el CheckBox queda con el valor anterior si no fuerzo pasar por la linea de asignación directa y esto teniendo en CheckBox un binding con un converter.

Despues de investigar vi que el problema esta, en que al cargar primer “Coche” si que funcionaba el “binding” pero luego al pasar por “cbIsClient.IsChecked = Coche.Cliente != null;” lo que sucede, es que XAML piensa que apartir de ahora asignación sera manual y borra el binding. Asi luego si comprobamos con “GetBindingExpression” veremos que no hay ningun binding.

Sabiendo esto ya podeis encontrar solución, en mi caso al trabajar en codigo tube que crear algo asi:

coche.Cliente = new Client("123456789");
BindingExpression be = cbIsClient.GetBindingExpression(ToggleButton.IsCheckedProperty);
be?.UpdateTarget();

Mi problema era que no podria acceder a la propiedad y no me saltaba trigger, asi que sin asignar directamente al control, lo que hacia es forzar el disparo del binding del control despues de cambiar el valor por el codigo.

Script para cambiar idioma (cultura) en toda la aplicación en C# WPF

Script que se aplica en arranque de aplicación, para cambio de idioma

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            Options options = Options.Create();
            string alternativeAdminCoreServiceUri = options.AdminCoreServiceUri;
            // Parte particular: inicio
            Admin.Clients.Core.AdminClient adminEntityClient = new Admin.Clients.Core.AdminClient(options.AdminCoreServiceUri, 
                                                                    alternativeAdminCoreServiceUri);
            bool changedFromLocal;
            adminEntityClient.GetGlobalParameterValues("C:", out changedFromLocal);
            string cultureStr = adminEntityClient.AdminSet.GetGlobalParameterStr(Common.SharedEntities.Admin.GlobalParameterValueId.CultureName);
            // Parte particular: final
            System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.GetCultureInfo(cultureStr);
            System.Threading.Thread.CurrentThread.CurrentCulture = culture;
            System.Threading.Thread.CurrentThread.CurrentUICulture = culture;

            WpfSingleInstance.Make(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, this);
            base.OnStartup(e);
        }
    }

Análisis de rendimiento en consultas MS Sql Server

Pequeño script para analizar rendimiento de consultas

SELECT [Metodo],Max([Tiempo]),SUM([Tiempo]), Count(*)
  FROM [MiDb].[dbo].[optimizacion]
  Group by [Metodo]
  Having Max([Tiempo]) > 0 and SUM([Tiempo]) > Max([Tiempo])
  order by Max([Tiempo]) desc;

SELECT [Metodo],Count(*)
  FROM [MiDb].[dbo].[optimizacion]
  group by [Metodo]
  having Count(*)>1
  order by Count(*) desc;

-- CacheData.IncidenciaGetAll Corregir cache
-- Especifico
SELECT * FROM [MiDb].[dbo].[optimizacion]
where [Metodo] = 'CacheData.IncidenciaGetAll';

Envió de correo electrónico con MailMessage en C#

Uno de los métodos para envió de correos electrónicos en C#. Codigo minimalista.

public static void CreateTestMessage2(string server)
{
	string to = "jane@contoso.com";
	string from = "ben@contoso.com";
	MailMessage message = new MailMessage(from, to);
	message.Subject = "Using the new SMTP client.";
	message.Body = @"Using this new feature, you can send an e-mail message from an application very easily.";
	SmtpClient client = new SmtpClient(server);
	// Credentials are necessary if the server requires the client 
	// to authenticate before it will send e-mail on the client's behalf.
	client.UseDefaultCredentials = true;

    try {
	  client.Send(message);
	}  
	catch (Exception ex) {
	  Console.WriteLine("Exception caught in CreateTestMessage2(): {0}", 
                  ex.ToString() );			  
    }              
}

Mas detalle de excepciones sobre EntitySet en C#

Como podemos mejorar la depuración de aplicaciones? Con mas información en el Log que escribimos en algún sitio (Eventos, Base de datos, fichero planto txt, etc.)

Código para sacar mas información cuando se producen problemas con entidades (longitud incorrecta en base de datos de los nvarchar, tipo diferente, etc.)

            catch (DbEntityValidationException e)
            {
                message = string.Empty;
                foreach (var eve in e.EntityValidationErrors)
                {
                    message += string.Format("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                        eve.Entry.Entity.GetType().Name, eve.Entry.State);
                    foreach (var ve in eve.ValidationErrors)
                    {
                        message += string.Format("- Property: \"{0}\", Error: \"{1}\"",
                            ve.PropertyName, ve.ErrorMessage);
                    }
                }
                message += ExceptionUtility.GetMessageFromException(e);
            }