Error: Validation failed for one or more entities

Si tienes este error al guardar una entidad en Entity FrameworkValidation failed for one or more entities. See ‘EntityValidationErrors’ property for more details“, es posible que te vuelvas loco buscando entre las propiedades de la excepción, cuál es el verdadero problema.

Para ello podemos utilizar el inspector rápido de Visual Studio (Shift + F9) y poner lo siguiente:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

Así veremos el detalle del error que estamos viendo, como podemos ver en la imágen:

excepcion-entity-validation-errors

 

Convertir encriptación en PHP 3DES en C#

Recientemente ha avisado que el sistema de pago por TPV virtual de Redsys se va a actualizar. En esta actualización se van a incorporar medidas de cifrado más potentes que la firma actual que se tiene implementado. Para ello los bancos han enviado cierta documentación (un poco tarde…) para hacer esta migración, puesto que el 23/11/2015 se supone que dejará de funcionar el sistema de encriptación actual.

Realizando la migración en mi empresa me he encontrado con un escollo que me ha costado un poco de solventar, y por lo que veo a muchos más desarrolladores de .NET les ha sucedido lo mismo. El problema está en el cifrado triple DES.

Este es el código de ejemplo que te facilitan en Redsys para realizar este cifrado.

function encrypt_3DES($message, $key){
// Se establece un IV por defecto
$bytes = array(0,0,0,0,0,0,0,0); //byte [] IV = {0, 0, 0, 0, 0, 0, 0, 0}
$iv = implode(array_map("chr", $bytes)); //PHP 4 = 4.0.2


// Se cifra
$ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv); //PHP 4 >= 4.0.2
return $ciphertext;
}


$key = $this->decodeBase64($key);
$ciphertext = $this->encrypt_3DES($message, $key);

La variable $message sería el texto a encryptar (en el caso de Redsys el número de pedido). La variable $key es la clave de encriptación de Redsys que previamente la decodificamos en Base64.
Al final obtenemos un resultado ($ciphertext) que es un array de bytes.

Ahora viene cuando hacemos lo mismo en .NET C#.


///
/// Uso de la encriptación TripleDES con IV todo 0 -> byte [] IV = {0, 0, 0, 0, 0, 0, 0, 0}
/// Esta encriptación se usa así para los TPV's de Redsys
///


///Texto a encriptar ///Clave de la encriptación en un array de Bytes ///
public static byte[] EncriptarTripleDES_IV_0(string texto, byte[] key)
{
using (TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider())
{
byte[] iv_0 = { 0, 0, 0, 0, 0, 0, 0, 0 };  //same IV that Redsys
byte[] toEncryptArray = Encoding.ASCII.GetBytes(texto);
tdes.IV = iv_0;
//assign the secret key
tdes.Key = key;
tdes.Mode = CipherMode.CBC;
tdes.Padding = PaddingMode.Zeros;
ICryptoTransform cTransform = tdes.CreateEncryptor();
//transform the specified region of bytes array to resultArray
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0,toEncryptArray.Length);
//Clear to Best Practices
tdes.Clear();
return resultArray;
}
}

Esta función nos devuelve el mismo resultado que la orginial proporcionada por Redsys en PHP.

El tipo ‘ObjectContent`1’ no pudo serializar el cuerpo de respuesta para el tipo de contenido

Si estás usando un Web API con Entity Framework, es posible que te salte este error “El tipo ‘ObjectContent`1’ no pudo serializar el cuerpo de respuesta para el tipo de contenido“, al intentar recuperar algún registro.

¿Por qué ha ocurrido esto?, bueno pues una de las posibles causas es que al intentar serializar con JSON, en nuestras tablas tenemos referencias a otras tablas (por ejemplo un foreign key) y la librería de NewtonJson nos diga que hay una referencia circular.

¿Como arreglamos este error?. Tendremos que incorporar las siguientes líneas de código o bien en el WebApiConfig.cs o bien en el Global.asax.cs

WebApiConfig

  
//Evito las referencias circulares al trabajar con Entity FrameWork         
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            
//Elimino que el sistema devuelva en XML, sólo trabajaremos con JSON
config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);

Global.asax

  
//Evito las referencias circulares al trabajar con Entity FrameWork         
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            
//Elimino que el sistema devuelva en XML, sólo trabajaremos con JSON
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);

Otra manera de localizar este problema es cuando nos aparece este mensaje de error:
An exception has occurred while using the formatter ‘JsonMediaTypeFormatter’ to generate sample for media type ‘application/json’. Exception message: Se han producido uno o varios errores.

Espero que os con esto se resuelva vuestro problema.

 

Habilitar conexiones remotas en SQL Server 2014

Quizás necesitemos conectarnos a una base de datos SQL Server 2014 que esté en un servidor remoto. Por defecto cuando instalamos SQL Server 2014 éste no viene habilitado para que éste acepte peticiones remotas, con lo que tendremos que hacer este proceso a mano. Para ello tenemos este sencillo manual que habilitará las conexiones remotas.

  1. Abrimos el Administrador de configuración de SQL Server 2014
    administrador-configuracion-sql-server-2014
  2. Seleccionamos la instancia (en caso de que tuviéramos más de una) de SQL Server que queremos habilitar las conexiones remotas.
    administrador-configuracion-sql-server-2014-tcp-ip
  3. Comprobamos si el Protocolo TCP/IP está Habilitado, en la pestaña “Protocolo”. En caso de que esté deshabilitado, haremos doble click y donde pone habilitado lo pondremos en “SI”.
  4. En la segunda pestaña en la de “Direcciones IP”, vamos al apartado IP4 e introducimos la IP de nuestro servidor. Ponemos el puerto TPC 1433. Dejamos en blanco los Puertos dinámicos TCP.
    habilitar-ip4
  5. Realizaremos un reinicio del servicio de SQL Server para que los cambios que hemos efectuado se apliquen a nuestro servidor.
  6. Con esto debería de ser suficiente para conectarnos remotamente. Pero si todavía no conseguimos hacerlo, tendremos que habilitar los puertos en el firewall de Windows.
    Los puertos a abrir son TCP 1433 y 1434 y UDP 1434.
  7. Si todavía no conseguimos conectarnos, podemos mirar que el servicio “Sql server Browser” esté en ejecución.

La mayor parte de este artículo vale tanto para la versión SQL Server 2014 como anteriores (e imagino que posteriores por la dinámica de Microsoft).

 

 

Error 404 – Enlaces permamentes con el nombre de la entrada en IIS

Recientemente al actualizar a la versión 3.9 de WordPress me encontré que los enlaces permanentes (permament links) en mis blogs dejaban de funcionar y daban un error 404.

Tras investigar un poco, porque me parecía raro que con la versión anterior si que funcionara pero con esta no, no encontré la causa de este error, pero si que encontré la forma de solucionarlo.

Para solucionar el problema con los enlaces permanentes en WordPress, tendremos que incorporar o sustituir nuestro web.config de cada web con estas líneas:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules><rule name="Main Rule" stopProcessing="true"><match url=".*"/><conditions logicalGrouping="MatchAll"><add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/><add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/></conditions><action type="Rewrite" url="index.php/{R:0}"/></rule>
<rule name="wordpress" patternSyntax="Wildcard">
<match url="*"/>
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="index.php"/>
</rule></rules>
</rewrite>
</system.webServer>
</configuration>

Espero que os sirva de ayuda.

Error: MySQL server has gone away

Si estamos importando una Base de datos o ejecutando una consulta bastante extensa, ya sea a través de PhpMyAdmin o MySQLWorkbench, es posible que nos aparezca este error:  MySQL server has gone away. Esto normalmente es por la longitud de textos o columnas.

Como solventaremos este error, pues tendremos que buscar nuestro archivo my.ini o my.cnf (dependiendo de la instalación y del servidor) y aplicar la variable que vemos a continuación.

max_allowed_packet=64

Si con esto no es suficiente ampliaremos los megas de esta forma:

max_allowed_packet=64*1024*1024

Estas variables deberán de ir después de la etiqueta [mysql]
Referencia aquí

 

 

Como añadir transparencia por CSS en mi web

La transparencia es algo que no se trata igual en todos los navegadores, por ello nos será muy útil esta clase de CSS, que está preparada para funcionar con los navegadores más actuales, sin meternos con los viejos internet explorer 7 y más atrás.

Pondremos en nuestra hoja de estilos .css la siguiente clase que luego aplicaremos en nuestra aplicación web.

.transparencia {
opacity: .25;
-moz-opacity: .25;
filter:alpha(opacity=25);
}

El navegador sabrá interpretar cuál es su propiedad que determina la transparencia y la aplicará sobre el elemento en la que utilicemos esta clase.

En principio, debería de funcionar sin problemas en las versiones nuevas de Internet Explorer, en Chrome, en Firefox y en Safari.

 

Como coger el favicon de otra web

El favicon es el icono que vemos en las pestañas de nuestro navegador cuando accedemos a cualquier web. Normalmente y si se ha personalizado suele tener algún dibujito relacionado con la página, o simplemente que es “gracioso” como el que tenemos en esta web.

Si quieres obtener o extraer la imágen del favicon de otra web lo puedes hacer con la siguiente URL que nos facilita Google:

http://www.google.com/s2/favicons?domain=NOMBREDOMinio

Donde sustituiríamos el nombre del dominio por el que queremos.

Ejemplo:

http://www.google.com/s2/favicons?domain=www.blogger.com
http://www.google.com/s2/favicons?domain=wikipedia.org
http://www.google.com/s2/favicons?domain=youtube.com
http://www.google.com/s2/favicons?domain=twitter.com
http://www.google.com/s2/favicons?domain=www.facebook.com
http://www.google.com/s2/favicons?domain=flickr.com
http://www.google.com/s2/favicons?domain=www.mozilla.org

Filezilla no guarda las contraseñas

Si vas a crear un nuevo sitio en Filezilla, y quieres guardar la contraseña para que cada vez que te conectes no te la pida, quizás te aparezca el siguiente mensaje:

“Has desactivado la opción de guardar la contraseña. ‘Normal’ and ‘Account’ logontypes are not available. Your entry has been changed to ‘Ask for password'”

Esto es un poco latoso porque te pide la contraseña siempre para acceder. Si queremos evitar esto, tendremos que ir a las opciones de Filezilla en Edición -> Opciones, luego pinchar en Interfaz y en las opciones de la derecha desmarcar en la zona de comportamiento la casilla de No guardar contraseñas.

Con esto ya tendríamos nuestro problema resuelto.

Servidor casero con direccion ip dinámica

Hace poco recibí un correo de Ángel a través del contacto de esta página preguntando lo siguiente:

Leí que estar en servidor casero montado por ti. yo monte uno también pero tuve que usar no-ip free porque mi dirección es dinámica. como tu lo hiciste en el tullo y que utilizaste? quiero aprender y resolver mi problema.
gracias

Como me pareció un tema bastante interesante he decido crear un post para explicar los métodos que utilizo yo, para solventar este problema.

Yo tengo montado un servidor en casa, precisamente donde está alojada esta página, entre otras. Actualmente tengo una dirección ip dinámica y esto ocasiona problemas de vez en cuando, puesto que si te cambia la dirección ip tu dominio, que está apuntando a la dirección ip de tu servidor, dejará de funcionar correctamente.

El cambio de dirección ip, aunque se tenga dinámica, depende de la configuración de nuestro proveedor de internet. En algunos casos cambia muy muy poco y en otros algo más a menudo. Lo normal es que si no se apaga el router la dirección ip no cambie por lo que normalmente tendremos que realizar pocos cambios.

¿Que ocurre si cambia?, si cambia nuestra ip de casa (o donde tengamos nuestro servidor), tendremos que meternos en los datos DNS de nuestro dominio y anotar la ip nueva.

En mi caso, tengo un programa creado por mí en .NET, que comprueba la dirección ip pública cada 15 minutos y si ha cambiado me manda un correo electrónico con la nueva dirección ip, por lo que lo antes posible procedo a actualizar la dirección ip en mi proveedor de dominios.

Aunque espero mejorar el programa y publicarlo para que lo pueda usar todo el mundo, la alternativa que uso con algunos clientes es http://www.noip.com/ con el que instalando un programita en el servidor siempre podrás acceder a él mediante una dirección (p.j. midirecciondecasa.no-ip.info).

Si tu ip ha cambiado, haciendo un ping a la dirección que tenemos registrada en noip.com, sabremos cuál es nuestra nueva dirección y procederemos a actualizarla en nuestro proveedor de dominios lo antes posible.