Archivo de la categoría: Diseño y Programación Web

Temas relacionados con el diseño y la programación Web en todos los lenguajes: html, php, asp.net, javascript, jquery…

Problema con scroll en ventana modal bootstrap

En bootstrap al abrir una ventana modal automáticamente se desactiva el scroll de la parte que se encuentra en el background.

Si al cerrar la ventana modal no consigue restablecerse el scroll se puede utilizar el siguiente cambio en el css:

Esto es el css que hace desaparecer el scroll

.modal-open {
    overflow: hidden;
}

Se puede modificar por lo siguiente

.modal-open {
    overflow: scroll;
}

De esta manera el scroll siempre estará activo.

 

Problema con scroll en ventana modal bootstrap
Valora este artículo

Utilizar AsyncPostBackTrigger o Update

Cuando utilizamos un UpdatePanel en Asp.Net WebForms a veces no tenemos en cuenta el uso final al que va destinado. Es decir, en ocasiones se hacen llamadas al servidor que no requieren un refresco del UpdatePanel con lo que no tiene sentido actualizarlo.

Entendiendo el UpdatePanel

Existe una propiedad fundamental para configurar el UdpatePanel y este es el UpdateMode. Puede tener 2 valores: Allways y Conditional.

Si establecemos este valor en Allways, todas las llamadas al servidor de los controles que produzcan un postback harán refrescar el panel. Esta es una opción muy rápida, que además viene por defecto, pero en mi opinión no nos ayuda nada a la hora de aprovechar al máximo los beneficios de AJAX y el UpdatePanel.

Estableciendo el valor UpdateMode en Conditional, deberemos preocuparnos nosotros de indicar qué controles realizarán el update en el panel o bien indicarle en nuestro código cuándo debe actualizarse.

Establecer los controles en la sección Triggers para indicar cuales de ellos producirán un update del panel puede parecer una buena opción, desde luego no está mal, pero ¿por qué deberíamos hacerlo si podemos indicarlo en el código mediante el método Update() del UpdatePanel?

La ventaja de utilizar el método Update() frente por ejemplo AsyncPostBackTriggers es que tenemos controlado en todo momento cuando se debe actualizar el UpdatePanel. Si, por ejemplo, tenemos un método en el servidor que responde a un click de un botón y dentro de este método tenemos condicionales que harán que el resultado sea o no visible para el usuario podremos indicar nosotros mismos cuando una acción alterará los datos visibles en pantalla mediante el método Update().

 

Utilizar AsyncPostBackTrigger o Update
4.5 (90%) 2 votes

Cerrar ventana modal bootstrap con un control asp.net

En ocasiones es necesario cerrar una ventana modal de bootstrap con un control asp que realiza una llamada al servidor para realizar ciertas acciones.

La solución es muy sencilla, solo hay que llamar al evento de cliente onclientclick del control:


<asp:Button runat="server" OnClientClick="$('#myModal').modal('hide');" Text="Grabar"/>

Cerrar ventana modal bootstrap con un control asp.net
4 (80%) 1 vote

Realizar tareas programadas en una aplicación ASP.Net

Desarrollo y programación .net

Por circunstancias de la vida me he encontrado últimamente con varios proyectos realizados en ASP.Net que requieren realizar tareas programadas que se ejecuten en un momento concreto del día independientemente si existe o no usuarios conectados.

Como suele ocurrir existen muchas maneras de abordar esta funcionalidad:

  • Mediante Servicios Windows, siempre que tengamos total control de nuestro servidor y el entorno para realizar la tarea en cuestión (Base de Datos, acceso al sistema de ficheros, etc.)
  • Mediante WCF. También sería necesario acceso total a IIS y a su configuración.
  • Mediante programación dentro de la misma aplicación ASP.Net.

Seguro que existe alguna otra pero mi objetivo primordial en todos estos proyectos que debía realizar era optimizar los tiempos mantenimiento, para ello creo que la última solución resultaba la mejor en este caso ya que solo tendría que dedicarme a modificar un único proyecto: la aplicación ASP.Net. De otro modo tendría que instalar el servicio windows o configurar el proyecto WCF dentro del IIS.

Así que me puse a investigar por la web cuales eran las mejores prácticas de cómo realizar una tarea programada en background dentro de ASP.Net. Encontré una solución que me parecía muy clara y que muchos reportaban como buena. Su funcionamiento requería del uso de la caché de la aplicación web y el método application_start dentro del global.asax.

Su uso consistía en añadir un objeto a la cache en el contexto de ejecución para que cuando dicha cache expirara utilizara el evento para ejecutar de nuevo la tarea. La palabra clave para este método es CacheItemRemovedCallback… pero os anticipo que yo NO LO UTILIZARÉ MÁS.

No voy a adentrar en los motivos de rehusar finalmente este método pero os puedo asegurar que da problemas, incluso cuando establecemos el tiempo de inactividad a 0 dentro del pool de aplicaciones del IIS, que en principio parecía que podía ser una de las soluciones.

Investigando un poco más pude dar con un componente muy interesante: Quartz.

Su uso es muy sencillo y parece ser que existe un componente homónimo en Java.

Quartz tiene una Interfaz denominada IJob que únicamente expone un método llamado Execute(). Si deseas hacer una tarea a nivel de aplicación únicamente debes llamar JobScheduler.Start() dentro de Application_Start() del Global.asax.

using Quartz;
using Quartz.Impl;
using System;
 
namespace ScheduledTaskExample.ScheduledTasks
{
    public class JobScheduler
    {
        public static void Start()
        {
            IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
            scheduler.Start();
 
            IJobDetail job = JobBuilder.Create&amp;lt;MyJob&amp;gt;().Build();
 
            ITrigger trigger = TriggerBuilder.Create()
                .WithDailyTimeIntervalSchedule
                  (s =&amp;gt;
                     s.WithIntervalInHours(24)
                    .OnEveryDay()
                    .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
                  )
                .Build();
 
            scheduler.ScheduleJob(job, trigger);
        }
    }
}
Realizar tareas programadas en una aplicación ASP.Net
4 (80%) 1 vote

10 consejos para programadores C#.Net

En esta entrada daremos 10 consejos para programadores C#.Net que puedan ser de utilidad y que en muchos casos no son muy conocidos.

Desarrollo y programación .net
Programador .Net
Consejo 1: Escribir pruebas unitarias para métodos no públicos

Seguro que si trabajas con proyectos que requieren un control de calidad has tenido que introducir algún proyecto de tests que impliquen pruebas unitarias. En ese caso seguro que has tenido problemas al intentar probar algún método que no es público. C# permite hacer visibles los ensamblados internos a otros ensamblados. Para solucionarlo añadiremos el siguiente atributo en el AseemblyInfo.cs.

//Hacer visible a un determinado ensamblado
[assembly: InternalsVisibleTo("MyTestAssembly")]
Consejo 2: Usar tuplas

En ocasiones es mejor utilizar una tupla contenedora de valores tipados que utilizar clases POCO, sobre todo cuando la estructura de datos creada solo se va a utilizar en un momento puntual.

public Tuple<int, string, string> GetEmployee()
{
	int employeeId = 1001;
	string firstName = "Rudy";
	string lastName = "Koertson";

	//Crear una tupla y devolverla
	return Tuple.Create(employeeId, firstName, lastName);
}
Consejo 3: No hay necesidad de crear colecciones temporales, mejor usar yield

Habitualmente creamos estructuras temporales de tipo enumerables para devolverlas en un método. Algo parecido a lo siguiente:

public List<int> GetValuesGreaterThan100(List<int> masterCollection)
{
	List<int> tempResult = new List<int>();

	foreach (var value in masterCollection)
	{
		if (value > 100)
			tempResult.Add(value);
	}
	return tempResult;
}

En estos casos podemos ahorrar un par de líneas de código utilizando el comando yield. A continuación mostramos el ejemplo anterior pero usando yield:

public IEnumerable<int> GetValuesGreaterThan100(List<int> masterCollection)
{
	foreach (var value in masterCollection)
	{
		if (value > 100)
			yield return value;
	}
}
Consejo 4: Comunicar que el método está obsoleto

Si tu librería está siendo usada por diferentes clientes y deseas que algún método deje de ser utilizado porque existe otro método que los sustituye o simplemente porque ya no funciona puedes indicarlo con el siguiente atributo:

[Obsolete("Este método estará obsoleto pronto. Para reemplazarlo se puede utilizar el método XYZ.")]
public void MyComponentLegacyMethod()
{
	//Aquí la implementación
}

El código anterior provocaría una advertencia o warning en el código que invocara este método. Sin embargo si deseas que ya no se pueda utilizar de ninguna de las maneras utilizarías un parámetro adicional boleano como True.

[Obsolete("Este método estará obsoleto pronto. Para reemplazarlo se puede utilizar el método XYZ.", true)]
public void MyComponentLegacyMethod()
{
	//Aquí la implementación
}
Consejo 5: Recuerda que las consultas de linq son diferidas

Cuando se realiza una consulta en linq solo se ejecuta realmente cuando se accede a los resultados. Esto se llama ejecución diferida. Para que solo se ejecute una vez la consulta debemos utilizar el método ToList.

public void MyComponentLegacyMethod(List<int> masterCollection)
{
	//Sin el método ToList esta consulta de linq sería ejecutada dos veces
	var result = masterCollection.Where(i => i > 100).ToList();

	Console.WriteLine(result.Count());
	Console.WriteLine(result.Average());
}
Consejo 6: Convertir entidades de negocio usando la palabra clave Explicit

Usar Explicit para definir la conversión de entidades. El método de conversión será invocado cuando se necesite. Un ejemplo:

class Program
{
	static void Main(string[] args)
	{
		ExternalEntity entity = new ExternalEntity()
		{
			Id = 1001,
			FirstName = "Dave",
			LastName = "Johnson"
		};
		MyEntity convertedEntity = (MyEntity)entity;
	}
}

class MyEntity
{
	public int Id { get; set; }
	public string FullName { get; set; }

	public static explicit operator MyEntity(ExternalEntity externalEntity)
	{
		return new MyEntity()
		{
			Id = externalEntity.Id,
			FullName = externalEntity.FirstName + " " + externalEntity.LastName
		};
	}
}

class ExternalEntity
{
	public int Id { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
}
Consejo 7: Mantener el Stack Trace original

En .Net cuando se usa un bloque catch para capturar una excepción y se vuelve a lanzar se pierde información ya que se entiende que se ha controlado y que la excepción se genera desde el bloque que la capturó. Ejemplo:

public void RunDataOperation()
{
	try
	{
		Intialize();
		ConnectDatabase();
		Execute();
	}
	catch (Exception exception)
	{
		throw exception;
	}
}

Para mantener la traza original del error haremos esto:

public void RunDataOperation()
{
	try
	{
		Intialize();
		ConnectDatabase();
		Execute();
	}
	catch (Exception)
	{
		throw;
	}
}
Consejo 8: Atributo Flags – Agrupamiento de enum

Mediante el atributo Flags dentro de una enumeración permitirá agrupar los valores de enum. A continuación un ejemplo en el que la salida será: “BlackMamba, CottonMouth, Wiper“.

class Program
{
	static void Main(string[] args)
	{
		int snakes = 14;
		Console.WriteLine((Reptile)snakes);
	}
}

[Flags]
enum Reptile
{
	BlackMamba = 2,
	CottonMouth = 4,
	Wiper = 8,
	Crocodile = 16,
	Aligator = 32
}
Consejo 9: Forzar el tipo base para un tipo genérico

Partamos de que hemos creado una clase genérica donde hay que cumplir que el tipo genérico previsto en la clase debe heredar de una interfaz específica, esto se puede hacer como se muestra en el ejemplo siguiente:

class MyGenricClass<T> where T : IMyInterface
{
	//Cuerpo de la clase iría aquí
}

O incluso a nivel de método:

class MyGenricClass
{
	public void MyGenericMethod<T>(T t) where T : IMyInterface
	{
		//Implementación genérica iría aquí
	}
}
Consejo 10: Exponer una propiedad como IEnumerable no significa que sea solo lectura

Imaginemos que creamos una clase con una propiedad de tipo IEnumerable, en este caso es posible modificar esta propiedad aunque sea solo de lectura. Un ejemplo:

class Program
{
	static void Main(string[] args)
	{
		MyClass myClass = new MyClass();
		((List<string>)myClass.ReadOnlyNameCollection).Add("######From Client#####");

		myClass.Print();
	}
}

class MyClass
{
	List<string> _nameCollection = new List<string>();
	public MyClass()
	{
		_nameCollection.Add("Rob");
		_nameCollection.Add("John");
		_nameCollection.Add("Jummy");
		_nameCollection.Add("Derek");
	}
	public IEnumerable<string> ReadOnlyNameCollection
	{
		get { return _nameCollection.AsEnumerable(); }
	}

	public void Print()
	{
		foreach (var item in ReadOnlyNameCollection)
		{
			Console.WriteLine(item);
		}
	}
}

En el código anterior hemos podido comprobar que la lista ha podido ser modificada cuando nuestra intención es que fuera solo de lectura. Para remediar esto podemos utilizar lo siguiente:

public IEnumerable<string> ReadOnlyNameCollection
{
	get { return _nameCollection.AsReadOnly(); }
}
10 consejos para programadores C#.Net
5 (100%) 4 votes

Comparativa de rendimiento de plantillas WordPress

Como sabemos desde hace algún tiempo en muchos casos se ha ido dejando de lado el rendimiento de los sitios web dando prioridad a otros aspectos como eran la “espectacularidad” del sitio y la inserción numerosos scripts por parte del programador que ralentizaban de manera increíble la carga de una página.

Esta tendencia está cambiando en gran parte a las preferencias de buscadores como google en la red .net a situar mejor a aquellos sitios que tienen una carga de página más liviana, y así de paso para promocionar sus servicios como por ejemplo page speed service.

La razón de realizar esta comparativa de rendimiento de plantillas WordPress es simplemente analizar la evolución en este aspecto de estas themes con respecto al rendimiento. Sabemos que existen numerosas plantillas en el mercado pero nos centraremos únicamente en las que proporciona WordPress al inicio de la instalación:

  • Twenty Fifteen
  • Twenty Fourteen
  • Twenty Thirteen

Para realizar la métrica utilizaremos PageSpeed Insights de Google.

Nota: existen factores externos de terceros que pueden afectar a la carga de una página como puede ser el servidor que aloja el sitio o la velocidad de transferencia, en nuestro caso y para que la comparativa sea más justa se ha procurado realizar esta comparativa en las mismas condiciones para todas las plantillas.

Twenty Fifteen

Resultado Móvil: 64 / Resultado Ordenador: 74

Rendimiento de Plantilla Twenty Fifteen

Twenty Fourteen

Resultado Móvil: 67 / Resultado Ordenador: 78

 

Rendimiento de plantilla Twenty Fourteen

Twenty Thirteen

Resultado Móvil: 68 / Resultado Ordenador: 83

Rendimiento de plantilla Twenty Thirteen

 

 

Resultado

Como vemos no hay grandes diferencias entre ellos pero estamos viendo que la evolución de las plantillas tampoco muestra una mejora en el rendimiento.

Comparativa de rendimiento de plantillas WordPress
5 (100%) 1 vote

Copiar y restaurar bases de datos MySQL con codificación de caracteres intacta

Si quieres preservar caracteres como ñ, ó, ç u otros del estilo cuando migras una base de datos MySQL deberás usar mysqldump con las siguientes opciones:

mysqldump -u <tu_usario> -p <tu_password> –default-character-set latin1 –skip- character-set <tu_db> archivo.sql

Para restaurarla:

mysql -u <tu_usuario> -p <tu_password> –default-character-set latin1 <tu_db> < archivo.sql 

Esto solucionará problemas al restaurar copias de seguridad mediante código. En mi código .Net realizaba un proceso que creaba tanto la copia de seguridad en scripts .sql y también tenía otro proceso que realizaba la copia de seguridad a partir del fichero generado anteriormente. Sin embargo si el comando lo ejecutaba a través de la consola de windows el proceso lo realizaba correctamente.

Aparentemente el primer proceso generaba correctamente el archivo sql pero a la hora de ejecutar el proceso no podía continuar cuando encontraba un caracter especial, (en mi caso la ñ).

Si realizas copias programadas también deberás tenerlo en cuenta sobre todo si ejecutas la restauración mediante alguna aplicación .net. Y sobre todo leer el fichero de esta manera:

StreamReader reader = new StreamReader(file,Encoding.GetEncoding(“latin1”));

Como ves los ingleses lo tienen más fácil porque nunca le ocurrirán problemas de este tipo a no ser que trabajen con aplicaciones multiidioma. Pero en cualquier caso deberías tener siempre en cuenta copiar y restaurar bases de datos MySQL con codificación adecuada.

 

Copiar y restaurar bases de datos MySQL con codificación de caracteres intacta
Valora este artículo

Code First – Resetear Entity Framework Migrations

Si trabajas con Code First, Entity Framework y Migrations es posible que a medida que avanzas en el proyecto llegues a un estado inconsistente de la base de datos cuando intentas actualizarla con el comando update-database.

Lo ideal es solucionarlo con las opciones que te puede ofrecer codefirst, pero si aún así llegas a un punto que creas necesario resetear las migraciones lo que deberás hacer es lo siguiente:

1. – Borrar el directorio Migrations de tu proyecto.
2. – Borrar la tabla _MigrationsHistory de tu base de datos.
3. – Ejecutar el siguiente comando en la consola de administración de paquetes.

Enable-Migrations -EnableAutomaticMigrations -Force

4. – Finalmente ejecutar:

Add-Migration Initial

Todo este proceso hace que se cree un nuevo archivo Initial.cs en la carpeta de Migrations. En él podrás ver (como siempre que realizas una migración) los métodos Up() y Down() que permiten la aplicación de la migración o el regreso al estado anterior.

En este punto antes de utilizar el comando update-database deberás tener en cuenta si quieres borrar la base de datos y partir con la base de datos vacía o aprovechar los datos que ya tenías previamente.

A) Si deseas partir con una base de datos vacía será tan sencillo como borrar todas las tablas de la base de datos y ejecutar update-database.
B) Si quieres aprovechar los datos deberás profundizar en el método Up() de la migración creada y ver que tablas quieres que se regeneren. Previamente a ejecutar update-database deberás borrar las tablas que te interesan resetear en tu base de datos y comentar las líneas de código que crean las tablas que deseas conservar en el método Up(). Una vez realizadas estas dos comprobaciones podrás utilizar el comando update-database.

Espero que este artículo te haya servido de ayuda para Resetear Entity Framework Migrations.

Code First – Resetear Entity Framework Migrations
4.5 (90%) 2 votes

Optimizar cache en IIS

En este post aprenderemos a optimizar cache en IIS editando el web.config.

Si tu servidor de alojamiento web es IIS puedes mejorar la velocidad de tu sitio estableciendo el tiempo de la caché insertando dentro de <system.webServer> del archivo web.config de la raíz de tu aplicación web:

<staticContent>
<clientCache cacheControlMode=”UseMaxAge” cacheControlMaxAge=”7.00:00:00″ />
</staticContent>

Donde cacheControlMode puede tomar los valores:

  • “NoControl”: no se establece un tipo de caché para el sitio, con lo que tomará los valores globales de configuración heredados.
  • “DisableCache”: caché deshabilitada para el sitio.
  • UseMaxAge: se especifica una edad de expiración de la caché en el parámetro cacheControlMaxAge en días, horas, minutos y segundos (d.hh:mm:ss)
  • UserExpires: indica la fecha exacta de expiración de la caché.
Optimizar cache en IIS
Valora este artículo