viernes, 12 de diciembre de 2014

Múltiples columnas de identidad especificadas

Si utilizas programación CodeFirst en tu proyecto .Net es posible que al realizar una modificación en el nombre de la columna que guarda la clave de una tabla/clase/DbSet aparezca el siguiente error al utilizar update-database con alguna migración pendiente.


Multiple identity columns specified for table ‘nombre_tabla’. Only one identity column per table is allowed.


Este error indica que existen múltiples columnas de identidad especificadas, es decir, codefirst entiende que existe más de una columna clave de la tabla.


Para solucionar este problema y hacer que la migración funcione deberás reordenar la lista de operaciones en el script de migración pendiente. Deberás ubicar las operaciones de borrado (drop) primero y luego añadir la columna con la nueva clave.


public partial class RenameKey : DbMigration
{
public override void Up()

DropPrimaryKey("dbo.nombre_tabla", new[] "OldId" );
DropColumn("dbo.nombre_tabla", "OldId");
AddColumn("dbo.nombre_tabla", "Id", c => c.Int(nullable: false, identity: true));
AddPrimaryKey("dbo.GameSummary", "Id");

 



Múltiples columnas de identidad especificadas

lunes, 10 de noviembre de 2014

Cadena de conexión MultipleActiveResultSets

El parámetro MultipleActiveResultSets dentro de una cadena de conexión permite mantener conjuntos de resultados múltiples. Si este parámetro se establece en false la aplicación debe procesar o cancelar todos los conjuntos de resultados antes de poder ejecutar cualquier otro dentro de esa conexión.


Un error típico cuando se dehabilita este parámetro es el siguiente:


There is already an open DataReader associated with this Command which must be closed first.


En una cadena de conexión MultipleActiveResultSets es un característica que funciona con sqlserver.



Cadena de conexión MultipleActiveResultSets

Cadena de conexión MultipleActiveResultSets

El parámetro MultipleActiveResultSets dentro de una cadena de conexión permite mantener conjuntos de resultados múltiples. Si este parámetro se establece en false la aplicación debe procesar o cancelar todos los conjuntos de resultados antes de poder ejecutar cualquier otro dentro de esa conexión.


Un error típico cuando se dehabilita este parámetro es el siguiente:


There is already an open DataReader associated with this Command which must be closed first.


En una cadena de conexión MultipleActiveResultSets es un característica que funciona con sqlserver.



Cadena de conexión MultipleActiveResultSets

Cadena de conexión MultipleActiveResultSets

El parámetro MultipleActiveResultSets dentro de una cadena de conexión permite mantener conjuntos de resultados múltiples. Si este parámetro se establece en false la aplicación debe procesar o cancelar todos los conjuntos de resultados antes de poder ejecutar cualquier otro dentro de esa conexión.


Un error típico cuando se dehabilita este parámetro es el siguiente:


There is already an open DataReader associated with this Command which must be closed first.


En una cadena de conexión MultipleActiveResultSets es un característica que funciona con sqlserver.



Cadena de conexión MultipleActiveResultSets

jueves, 30 de octubre de 2014

Copiar una solución quitando git

Si tenemos una aplicación en visual studio que está enlazada a git y queremos copiarla en otro lugar quitando git lo que hay que hacer es tan sencillo como copiar el contenido de toda la solución salvo los ficheros de git.


¿Cuáles son los ficheros de git en una solución de visual studio?


Son los siguientes:


contenidogitsolucionvs


Si nos fijamos el directorio .git está como fichero oculto y para visualizarlo será necesario que cambies tu configuración del explorador de ficheros de windows.


Para copiar una solución quitando git lo que deberás borrar son estos ficheros una vez copiada.



Copiar una solución quitando git

martes, 28 de octubre de 2014

Error de validación de viewstate MAC

En el supuesto de que instales tu aplicación web en una granja de servidores debes tener en cuenta que es posible que la validación del viewstate no se comporte correctamente. Como sabemos para un programador esto es un problema porque son errores que no se producen en nuestro equipo local de desarrollo sino que es en el despliegue.


El error

El error en cuestión es el siguiente:


Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey>….


ViewState MAC Farm


¿Por qué este error?

Como sabemos en asp.net existe el concepto del viewstate que permite guardar el estado de ciertos controles y partes de la página para ser reutilizados después de un postback. Esto que a priori es una ventaja implica el inconveniente de que un usuario malintencionado envíe una carga _VIEWSTATE y engañe a la aplicación y realice una acción que no se debería realizar.


Para evitar este tipo de ataque el campo _VIEWSTATE se protege codificándolo con un código de autenticación de mensajes (MAC). ASP.Net valida el MAC que se envía con la  carga cuando se produce un postback, si no coincide se produce un error en la validación del viewstate.


La clave que se utiliza para calcular el MAC está en el elemento machineKey de la aplicación en el archivo web.config.


Una de las causas más comunes que provocan este error es que nuestra aplicación está en una granja de servidores, en este caso cada uno de los servidores generará una machineKey para nuestra app y entonces ninguno acordará cual aplicar.


Solución

La mejor solución y más sencilla es aplicar una machineKey explícitamente en nuestro web.config. De esta manera cualquier servidor que pretenda ejecutar nuestra aplicación utilizará de manera obligada la clave que le establezcamos en este fichero.


¿Cómo generamos nuestra clave machinekey?

Para generarlo tenemos varias maneras pero yo recomiendo nunca utilizar sitios web donde se generan automáticamente ya que no sabemos si estas claves se han generado de forma segura o son guardadas para posibles usos malintencionados, buff ya sé que suena muy rebuscado pero no nos podemos fiar, solo debemos usar las claves generadas por nosotros mismos.


En este link podemos ver varias maneras para crear el machine.config.


¿En qué sección del web.config editamos nuestra machinekey?

El elemento <machineKey> solo es válido en el archivo Web.config en la raíz de la aplicación y no es válido en el nivel de subcarpeta (location).


<configuration>
<system.web>
<machineKey ... />
</system.web>
</configuration>

 



Error de validación de viewstate MAC

jueves, 2 de octubre de 2014

Problema con edmx al publicar en Azure

Espero que no tengas el siguiente problema con edmx al publicar en Azure.


Primero expongo la situación en la que me encontré:


Empecé a desarrollar un proyecto con Visual Studio 2013 en el que partía de una base de datos SQLServer Azure ya creada. Añadí un elemento de edmx para crearme las entidades de la base de datos así como las vistas y procedimientos almacenados.


En mi equipo local conectaba con esta base de datos y el contexto de Entity Framework también funcionaba correctamente ya que conseguí agregar el origen de datos de una tabla a mi GridView.


Pues bien, cuando terminé mi desarrollo y me decidí por publicarlo en Azure al llegar a cualquier pantalla donde necesitaba acceder a los datos me daba el siguiente error:


…SQLException Invalid Object Name “dbo.NombreTabla”…


Lo que aparentemente dice este error es que no existe la tabla en la base de datos a la cual me conectaba. Esto me parecía increíble porque ni siquiera estaba trabajando con la base de datos local sino que en el momento de la programación atacaba directamente a la base de datos en Azure y… funcionaba y seguí funcionando, con lo que la cadena de conexión debería de ser la misma.


Después de darle muchas vueltas observé que aparte de publicar mediante la opción “Web Deploy” existe la opción de publicar mediante “ftp”. Decidí publicar en azure mediante ftp y finalmente conseguí que funcionara.


Aún no sé porque el método “Web Deploy” no funcionaba correctamente pero si alguien sabe o intuye por qué por favor que nos lo comente.


 


 



Problema con edmx al publicar en Azure

lunes, 29 de septiembre de 2014

Cómo localizar identity de asp net

En esta entrada haremos una pequeña explicación de cómo localizar identity de asp net.


Cuando utilizamos esta nueva característica de asp.net nos daremos cuenta que los mensajes de error propios de la validación tanto de la entidad como de negocio aparecen siempre en inglés.


La solución más sencilla para poder utilizar otras traducciones de identity será la instalación de un paquete a través de la consola de administración de paquetes con el siguiente comando:


install-package Microsoft.AspNet.Identity.Core.xx


Las últimas letras indican el idioma que queramos instalar, por ejemplo para español sería es.


install-package Microsoft.AspNet.Identity.Core.es


Una vez instalado los errores aparecerán (en este caso concreto) en castellano.



Cómo localizar identity de asp net

Cómo localizar identity de asp net

En esta entrada haremos una pequeña explicación de cómo localizar identity de asp net.


Cuando utilizamos esta nueva característica de asp.net nos daremos cuenta que los mensajes de error propios de la validación tanto de la entidad como de negocio aparecen siempre en inglés.


La solución más sencilla para poder utilizar otras traducciones de identity será la instalación de un paquete a través de la consola de administración de paquetes con el siguiente comando:


install-package Microsoft.AspNet.Identity.Core.xx


Las últimas letras indican el idioma que queramos instalar, por ejemplo para español sería es.


install-package Microsoft.AspNet.Identity.Core.es


Una vez instalado los errores aparecerán (en este caso concreto) en castellano.



Cómo localizar identity de asp net

miércoles, 17 de septiembre de 2014

Envío de Mails con ELMAH

El envío de mails con ELMAH es una de las muchas virtudes que tiene este sistema de control de errores. En este post intentaré explicar cómo se configura.


Nota: partiremos de una instalación correcta de ELMAH. Si no sabes instalar y configurar ELMAH te recomiendo este post.


Paso 1: configurar una cuenta de correo en el web.config.


En realidad este paso no es propio de ELMAH, en el web.config se puede establecer muchos parámetros que puedes o no utilizar cuando desarrolles tus aplicaciones o software.


Para añadir una cuenta de correo deberemos abrir una sección llamada <system.net> dentro de la raíz <configuration> del web.config.


Como una imagen vale más que mil palabras aquí está la configuración completa:


Envio de mails con ELMAH


Como vemos establecemos el servidor  smtp, el puerto, el nombre de usuario y la contraseña de la cuenta.


Paso 2. Indicar a ELMAH datos del envío de correo.


El segundo paso sí que tiene lugar en la sección propia de ELMAH dentro del web.config. De nuevo podemos en una imagen como configurarlo:


Configurar envio mail con elmah


En la imagen vemos que estableceremos el campo “from” (dirección remitente del correo), el campo “to” (destinatario) y el asunto “subject”.


Si nos fijamos el asunto tiene el código 0 que indica que en esa posición se sustituirá el mensaje del error de tal modo que el destinatario podrá ver de una manera rápida en que consiste el problema.



Envío de Mails con ELMAH

martes, 16 de septiembre de 2014

Modificar url de acceso elmah axd

Por seguridad es mejor cambiar la url donde se accederá a los errores de aplicación de ELMAH. Como sabemos en el momento de la instalación la url de acceso es la siguiente:


http://”misitio.com”/elmah.axd


Si queremos cualquier otra como por ejemplo:


http://”misitio.com”/mis_errores.axd


Deberemos reemplazar en el web.config todas las ocurrencias que encontremos de “elmah.axd” por “mis_errores.axd”



Modificar url de acceso elmah axd

lunes, 15 de septiembre de 2014

Acceso remoto en ELMAH

El acceso remoto en ELMAH por defecto está desactivado.


Esto quiere decir que solo podremos acceder a nuestra pantalla de monitorización si accedemos desde la misma IP donde está el hosting de nuestra aplicación.


Dependiendo si queremos acceder únicamente desde nuestro equipo servidor o desde cualquier equipo tenemos la posibilidad de configurarlo a través del web.config.


Dentro de la sección de configuración <elmah> existe una etiqueta <security> donde su propiedad “allowremoteaccess” nos permitirá activar o desactivar el acceso remoto.


acceso remoto elmah


 



Acceso remoto en ELMAH

domingo, 14 de septiembre de 2014

Instalar y configurar ELMAH

Como todos sabemos el trabajo de un programador no es perfecto y por eso, haciendo caso al refrán,  es mejor prevenir que curar.  Un buen desarrollador de software tendrá en cuenta crear un log para monitorizar aquellos errores de programación y de cualquier otro tipo que puedan suceder en la aplicacíón que se desarrolla.


Al respecto el programador tiene varias opciones:


  • Crearse por sí mismo un sistema de control de errores dentro de su aplicación. Si es hábil podrá migrar este sistema a futuros desarrollos.

  • Utilizar librerías ya implementadas que cubren la funcionalidad de control de errores.

En mi caso yo recomiendo ELMAH (Error Logging Modules and Handlers) que permite crear un sistema automático de guardado de errores y además crear la infraestructura (tablas y procedimientos en base de datos y librerías .Net) para utilizarlas como servicio de logging.


Este post intentará explicar cómo instalar y configurar ELMAH para una aplicación o sitio web en asp.net.


Paso 1. Descargar las librerías de ELMAH.


El primer paso que deberás hacer es descargarte las librerías de ELMAH en tu sitio web asp.net. Esto lo puedes hacer manualmente (en este enlace) o mediante el administrador de paquetes NuGet de Visual Studio (Menú Tools – Library Package Manager – Manage NuGet Packages for Solution…)


Instalar y configurar ELMAH


En la ventana emergente buscaremos en nuget.org (Online) con la palabra clave ELMAH y lo instalaremos en nuestra aplicación Web.


Una vez instalado veremos que nos ha referenciado algunas librerías nuevas y nos habrá modificado el web.config.


Paso 2. Ejecutar el script de la base de datos.


ELMAH puede utilizar una base de datos sqlserver para guardar los errores que se van generando. El siguiente paso será crear la estructura de la base de datos a través de un script que podremos descargar aquí.


Paso 3. Utilizar la monitorización de errores.


En este punto ya podremos ver una de las ventajas de ELMAH. Utilizaremos la url http://”misitio.com”/elmah.axd para monitorizar los errores por pantalla.


Por ejemplo,


si lanzamos una excepción manualmente en nuestro código…


ELMAH Excepción manual


lo ejecutamos y después de lanzado el error vamos a la url http://”misitio.com”/elmah.axd veremos una pantalla donde aparece lo siguiente:


Error monitorización ELMAH


Es útil, pero en este punto el error no se ha guardado en la base de datos, de hecho si no te interesa guardarlo en un almacenamiento persistente podrás saltarte el paso 2 y los siguientes.


Paso 4. Configurar la base de datos.


Para enlazar ELMAH con la base de datos es necesario indicarle cual es la cadena de conexión. Para ello deberemos ir al web.config y añadir la cadena de conexión dentro de la sección que define la etiqueta <elmah>


ELMAH cadena de conexión


Si nos fijamos en la etiqueta errorLog, se le está indicando que para el tipo de módulo sqlerrorlog utilice la cadena de conexión con el nombre “DefaultConnection” que la hemos definido previamente en el web.config.


Si la cadena de conexión es correcta los errores se empezarán a guardar en este punto en la base de datos.


En futuros posts veremos algunas configuraciones extra que podemos utilizar con ELMAH como son el envío de mails, seguridad, etc…


 



Instalar y configurar ELMAH

lunes, 11 de agosto de 2014

Qué es Visual Studio LightSwitch

Con esta tecnología Microsoft pretende llevar el campo de desarrollo a manos que no se dedican especialmente a la programación.


Su utilización se asemeja a lo que pueda ser access comparado a cualquier gestor de base de datos.


En visual studio 2013 puedes elegir entre crear una aplicación LightSwitch de escritorio o una de tipo web.


Si bien todas estas soluciones rápidas de desarrollo son muy poco personalizables puede llegar en alguna ocasión a ser interesante para desarrollar una aplicación de una manera rápida y sencilla.


Más Info



Qué es Visual Studio LightSwitch

domingo, 10 de agosto de 2014

Como añadir una nueva entrada a un fichero po y mo

Si utilizas la aplicación Poedit para editar tus traducciones de WordPress te habrás fijado que no existe ningún botón ni ninguna opción para añadir una nueva fila o traducción al fichero.


Para poder añadir una nueva entrada a un fichero po y mo tan solo debes olvidarte al principio de Poedit y editarlo con un procesador de textos cualquiera (por ejemplo notepad++) y copiar una fila como la siguiente.


#: ../header.php:391 ../header.php:442

msgid “Just type and press ‘enter’”

msgstr “Teclea y pulsa intro”


La primera fila es un comentario que indica en que sitios se está utilizando la traducción.


La segunda fila (la que empieza por msgid) significa que el id del mensaje es lo que va entre comillas. Lo ideal es que para todos tus ficheros de idiomas existan los mismos ids. Es común sobretodo cuando descargas plantillas que se hayan olvidado en los ficheros de traducción algunas claves con lo que la traducción no se realizará. En este caso obtendrá el valor por defecto que contiene el fichero de idioma por defecto.


La tercera fila (comienza por msgstr) es el sitio donde se realiza la traducción en el idioma que pertenezca el fichero a editar.


Una vez hemos introducido estas 3 filas con su correspondiente traducción al idioma y guardado el archivo po podremos abrir este mismo archivo con Poedit. Ahora podremos ver que con esta app se visualiza la nueva entrada que anteriormente no estaba.


El último paso es guardar con Poedit y se generará o actualizará el fichero mo.


Estos dos últimos ficheros (po y mo) son los que utilizaremos para su correcta traducción.



Como añadir una nueva entrada a un fichero po y mo

sábado, 9 de agosto de 2014

Eventos de ratón para un marcador en Google Maps

A continuación se enumerarán los distintos eventos que son disparados cuando se interactua con el ratón sobre un marcador de Google Maps.




google.maps.event.addListener(marker, "click", function (e) log("Click"); );
google.maps.event.addListener(marker, "dblclick", function (e) log("Double Click"); );
google.maps.event.addListener(marker, "mouseover", function (e) log("Mouse Over"); );
google.maps.event.addListener(marker, "mouseout", function (e) log("Mouse Out"); );
google.maps.event.addListener(marker, "mouseup", function (e) log("Mouse Up"); );
google.maps.event.addListener(marker, "mousedown", function (e) log("Mouse Down"); );
google.maps.event.addListener(marker, "dragstart", function (mEvent) log("Drag Start: " + mEvent.latLng.toString()); );
google.maps.event.addListener(marker, "drag", function (mEvent) log("Drag: " + mEvent.latLng.toString()); );
google.maps.event.addListener(marker, "dragend", function (mEvent) log("Drag End: " + mEvent.latLng.toString()); );



Eventos de ratón para un marcador en Google Maps

viernes, 8 de agosto de 2014

Google Maps: crear un marcador con etiqueta

Antes de nada hay que indicar que es necesario añadir la referencia a la api de google maps para realizar lo que hace este post. Para crear un marcador que muestre una etiqueta con Google Maps podremos seguir el siguiente ejemplo. Marcador-google-maps


Crear un marcador básico


La clase google.maps.InfoWindow será la que nos permita visualizar la etiqueta. Estará asociada a un mapa y un marcador cuando decidamos abrirla con el comando: iw.open(map, marker); Si nos fijamos el lugar donde se mostraría la información sería en el click del marcador ya que hemos registrado un manejador del evento correspondiente en la última línea, esto desencadenará la visualización de la etiqueta.


var latLng = new google.maps.LatLng(49.47805, -123.84716); var homeLatLng = new google.maps.LatLng(49.47805, -123.84716); var map = new google.maps.Map(document.getElementById('map_canvas'), zoom: 12, center: latLng, mapTypeId: google.maps.MapTypeId.ROADMAP ); var marker = new MarkerWithLabel( position: homeLatLng, draggable: true, map: map, labelContent: "A", labelAnchor: new google.maps.Point(22, 0), labelClass: "labels", // la clase CSS para la etiqueta labelStyle: opacity: 0.75 ); var iw = new google.maps.InfoWindow( content: "Home For Sale" ); google.maps.event.addListener(marker, "click", function (e) iw.open(map, marker); ); 


Google Maps: crear un marcador con etiqueta

jueves, 7 de agosto de 2014

Problema con firma en Outlook, una imagen ha dejado de mostrarse

Puede que te ocurra esto…


Has estado mandando correos con tu firma que contiene una imagen sin problemas hasta el día de hoy, pero de la noche a la mañana la imagen ya no se ve como debería en los nuevos correos que envías. Cuando redactas el correo la imagen no se ve y en su lugar aparece una imagen tipo auto-forma que puedes girar, expandir o contraer.


Esto es lo que le pasó a una persona que trabaja conmigo y aprovechó que estaba por ahí para pedirme que lo arreglara… ¡sí hombre! ¡como si yo conociera Outlook al dedillo!


El caso es que después de darle algunas vueltas sin encontrar solución decidí reiniciar el programa y de esta manera tan sencilla se solucionó.


 



Problema con firma en Outlook, una imagen ha dejado de mostrarse

viernes, 1 de agosto de 2014

Bases de datos para desplegar con una aplicación .Net

Cómo realizar una instalación de una aplicación nativa en cliente que utilice una base de datos pero sin tener que realizar la instalación completa de sqlserver u oracle por ejemplo que dificultan el despliegue de todo el sistema.


Para solucionar este problema, de momento, he encontrado estas soluciones.


  • Desplegar una base de datos de tipo SQL Server CE (Compact Edition) junto a la aplicación. Cómo desplegar una Base de datos SQL Server Compact con una aplicación.

  • Utilizar SQLite. Es una base de datos que se integra en ficheros casi planos y que es fácil de desplegar con una solución en Visual Studio. Existe una librería en .Net (System.Data.SQLite.dll) que permite acceder. También debe funcionar con Entity Framework pero esto todavía no lo he podido comprobar.

  • Siempre puedes usar un fichero Access para este tipo de despliegues.

 



Bases de datos para desplegar con una aplicación .Net

miércoles, 30 de julio de 2014

Pantalla completa en WPF

Para hacer una ventana a pantalla completa en WPF solo es necesario introducir los siguientes atributos a la etiqueta window:


WindowState=”Maximized”


WindowStyle=”None”


 



Pantalla completa en WPF

viernes, 11 de julio de 2014

Crear marcadores en Google Maps con la API

Otra de las cosas muy interesantes que nos permite la API de google maps es poder utilizar los marcadores que queramos y situarlos a nuestro antojo dentro de un mismo mapa. Incluso podemos vincular este marcador con una url de tal modo que al hacer click sobre él nos lleve a otro contenido dentro de Internet.


Obtener la capa y asignarle al objeto “mapa”

En un principio deberás tener colocada dentro de tu página una capa vacía donde querrás ubicar el mapa. Lo normal será rellenar el mapa en el momento que carguemos la página.




...

<div id="map_canvas"></div>

...


Con jquery podemos utlizar el evento onload de la ventana para realizar todas las operaciones del mapa.




window.onload = function ()  

//Creamos las opciones que estarán asignadas al mapa

var options =
mapTypeControlOptions:
mapTypeIds: ['Styled']
,
center: new google.maps.LatLng(39.644024, -3.185656),
zoom: 5,
disableDefaultUI: true,
mapTypeId: 'Styled'
;
var div = document.getElementById('map_canvas');  //En esta línea obtenemos la capa donde se ubicará nuestro mapa

//Creamos el objeto mapa de google con las opciones y asignamos la capa div html
var map = new google.maps.Map(div, options);




 


Cómo crear el marcador

Para crear un marcador es necesario dos objetos de google que son:


  • google.maps.Marker, será el propio marcador.

  • google.maps.LatLng, objeto que representa las coordenadas dentro del mapa.

Primero creamos un objeto LatLng , en él fijaremos la longitud y latitud del marcador.




var gijon = new google.maps.LatLng(43.532362, -5.661588);


Posteriormente creamos el marcador:




var marker_gijon = new google.maps.Marker(
position: gijon,
url: '/sedes/sede-gijon/',
title: 'Gijón',
map: map
);


En este punto podemos ver en la propiedad “position” le asignamos la variable de tipo LatLng establecido previamente.


Title, será la cadena que se mostrará al pasar el ratón por encima.


Y “map” es el objeto mapa creado anteriormente.


La propiedad url no existe como tal en el objeto de google marker pero la creamos nosotros para establecer la dirección a la que se dirigirá posteriormente.


Para tratar esta dirección podemos utilizar el siguiente código:




google.maps.event.addListener(marker_gijon, 'click', function()
window.location.href = marker_gijon.url;
);


Este ha sido un pequeño tutorial para crear marcadores en Google Maps con la API. Seguro que existen más posibilidades pero esto es solo una manera sencilla de empezar.



Crear marcadores en Google Maps con la API

lunes, 7 de julio de 2014

Firmas DKIM y SPF para programación Newsletter

En el envío de correos electrónicos masivos se corre el riesgo de que los correos sean tratados como Spam. En este caso la IP desde la cual se envía el correo electrónico seguramente quedará añadida a la lista negra de servidores. En el caso de que esto suceda estarás en un grave problema ya que es complicado revertir este problema.


El origen del problema


Mediante programación se puede falsear el campo “From” desde el cual se envía un correo electrónico. Esta característica hace que un usuario que entienda un poco de programación pueda enviar uno o varios correos electrónicos con la dirección remitente falseada.


De Wikipedia:


… El correo masivo supone actualmente la mayor parte de los mensajes electrónicos intercambiados en Internet, siendo utilizado para anunciar productos y servicios de dudosa calidad. Rolex, eBay y viagra son los asuntos de los mensajes que compiten por el primer lugar en las clasificaciones de spam.


Usualmente los mensajes indican como remitente del correo una dirección falsa. Por esta razón, no sirve de nada contestar a los mensajes de spam: las respuestas serán recibidas por usuarios que nada tienen que ver con ellos. Por ahora, el servicio de correo electrónico no puede identificar los mensajes de forma que se pueda discriminar la verdadera dirección de correo electrónico del remitente, de una falsa. Esta situación que puede resultar chocante en un primer momento, es semejante por ejemplo a la que ocurre con el correo postal ordinario: nada impide poner en una carta o postal una dirección de remitente aleatoria: el correo llegará en cualquier caso. No obstante, hay tecnologías desarrolladas en esta dirección: por ejemplo el remitente puede firmar sus mensajes mediante criptografía de clave pública.


Los filtros automáticos antispam analizan el contenido de los mensajes buscando, por ejemplo, palabras como rolex, viagra, y sex que son las más usuales en los mensajes no deseados. No se recomienda utilizar estas palabras en la correspondencia por correo electrónico: el mensaje podría ser calificado como no deseado por los sistemas automáticos anti correo masivo…


Soluciones


Para indicar que el remitente del correo electrónico es realmente quién dice ser se han propuesto algunas soluciones.


Los sistemas más utilizados para este fin son:


  • SPF

  • DKIM

SPF

Consiste en indicar en el DNS del dominio a configurar cuales serán las máquinas que están autorizadas para enviar correos electrónicos. Como es el propietario del dominio el único autorizado que puede modificar el registro DNS entonces puede indicar que equipos (IPs) pueden realizar el envío bajo su nombre.


En el servidor de  correo entrante del destinatario se comprobará los registros DNS del dominio del remitente. Si la dirección IP del servidor que ha enviado el correo concuerda con lo que nos dice el DNS que es una máquina autorizada entonces el correo quedará autenticado en SPF.


SPF es una extensión del protocolo SMTP.


Ver + info en Wikipedia.


DKIM

Consiste en firmar cada correo electrónico enviado. Esto se realiza mediante la utilización de una clave pública que permita ser verificado por cada destinatario.


El proceso incluye la inserción de una firma DKIM en las cabeceras del mensaje. El receptor se encarga de validar la firma obteniendo la clave pública a través del DNS.


DKIM es independiente del protocolo SMTP. Únicamente actúa sobre el cuerpo y cabeceras del mensaje y no en la conversación SMTP.


Ver +info en Wikipedia


Conclusiones


Estos dos sistemas son complementarios y no se excluyen entre sí. De hecho lo ideal sería mantener los dos si tienes que implementar un software de envío masivo de correos para evitar entrar en las dichosas listas negras.


A nivel de programador / desarrollador existen unas diferencias:


  • En el caso de SPF no es necesario tocar “código” ya que únicamente se modifica el DNS del dominio que realizará los envíos.

  • En el caso de DKIM, es necesario tocar el DNS y además el programador deberá tener en cuenta que debe firmar el correo antes de enviarlo mediante programación.

Lo que a priori parece una tarea sencilla para el programador, el envío de boletines de noticias se torna complicada cuando descubrimos que podemos ser tratados como spam.


La programación Newsletter no es tan sencilla. Esperamos que aquí hayáis encontrado la manera de realizarlo sin problemas de ser tratados como no deseados.


 



Firmas DKIM y SPF para programación Newsletter

jueves, 26 de junio de 2014

Dar estilo a los mapas de google

Antes de nada decir que para dar estilo a los mapas de google es necesario utilizar la API de Google Maps.


Una vez dado de alta en este servicio se te ofrecerá un número de cliente que utilizarás para acceder a todas sus características.




<script src="http://maps.googleapis.com/maps/api/js?client=numerodecliente&sensor=true_or_false"
type="text/javascript"></script>


Una vez añadido este código javascript. Podremos modificar los estilos de nuestro mapa a nuestro antojo. La referencia donde encontrarás toda la documentación es la siguiente:


https://developers.google.com/maps/documentation/javascript/reference?hl=es-ES


En este enlace podremos ver ejemplos de distintos estilos de mapas que podremos pintar:


Para utilizar correctamente cada uno de los ejemplo se ha de crear una capa con id=”map”. Esta capa será la que al cargar la página contenga el mapa.


 


 


 


 


 



Dar estilo a los mapas de google

domingo, 15 de junio de 2014

Comprobar si tu correo está en listas negras

A veces Internet tiene vida propia y aunque tu no te dediques a enviar spam o envíos masivos automáticos siempre viene bien comprobar si tu dominio o dirección de correo electrónico se ha metido en una lista negra por alguna razón incomprensible.


La mejor manera de comprobarlo es a través de la herramienta online mxtoolbox.com.


Entre otras cosas con esta herramienta puedes:


  • Consultar información sobre el valor MX de un dominio

  • Puedes comprobar si la dirección IP de un servidor de mail está registrado como fuente de spam.

En esta web puedes registrarte y hacer que te envíen informes periódicos para comprobar si tu correo está en listas negras.



Comprobar si tu correo está en listas negras

lunes, 2 de junio de 2014

¿Donde está alojado un dominio?

En algunas ocasiones necesitamos saber donde está alojado un dominio. La herramienta whois nos permite conocer la información asociada a un dominio pero con ella no podemos ver el lugar donde está alojado el dominio.


Para consultar esta información podemos utilizar whoishostingthis.com.


 



¿Donde está alojado un dominio?

lunes, 19 de mayo de 2014

Error: The message received from the server could not be parsed

Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed


Si te encuentras con este error seguramente estés utilizando UpdatePanel… ¿no es así?


Incluso es posible que te pase inadvertido si no tienes activado el depurador de javascript.


E hilando más fino… ¿este error solamente te aparece en Internet Explorer?


Si todas tus respuestas han sido “sí” entonces es posible que te estés encontrando con el mismo problema con el que me encontré yo.


Te comento la manera en que yo solucioné este error:


Borrar cualquier código javascript que tengas dentro del updatepanel y sitúalo fuera.


Espero que te haya servido.



Error: The message received from the server could not be parsed

viernes, 9 de mayo de 2014

Hacer ISO desde múltiples ficheros de rar

Muy fácil pero antes debes tener instalado el winrar.


1. Vas a la carpeta donde están los ficheros.


2. Seleccionar todos los ficheros. (Ctrl-e)


3. Click derecho sobre cualquiera de uno de ellos y pulsas extraer aquí.


Cuando finalice el trabajo winrar te habrá creado un fichero iso.



Hacer ISO desde múltiples ficheros de rar

lunes, 5 de mayo de 2014

Problemas con OWIN en un hosting compartido

Si vas a desarrollar una aplicación asp.net con OWIN y piensas alojarla en un servidor compartido debes tener esto en cuenta.


En muchos proveedores de hosting compartido tienen configurado en IIS el nivel de confianza high, medium, low… pero no está “Full”.


Esto es importante porque los ensamblados OWIN necesitan para su perfecta ejecución el nivel de confianza Full. (trust level=”Full”). Este parámetro se puede configurar en el web.config pero será inútil ponerlo si a nivel de máquina el machine.config no permita sobrescribirlo.


trust_level


 



Problemas con OWIN en un hosting compartido

viernes, 2 de mayo de 2014

ValidationSummary salta al inicio de la página

Este problema surge cuando en una página ASP con scroll se tiene un control Validation Summary. Al pulsar el botón que desencadena la validación en cliente la página “sube” hasta arriba cuando en muchos casos lo deseable es que no se mueva.


Si se quita el Validation Summary el salto no lo hace.


Para solucionar este problema existen dos soluciones:


  • Trabajar la validación únicamente en servidor, esto significa desactivar validaciones de cliente para todos los controles de validación (EnableClientScript=”false”)

  • Deshabilitar la función ScrollTo de javascript. Esto sería con este código:



<script type="text/javascript">
window.scrollTo = function()
</script>



ValidationSummary salta al inicio de la página

viernes, 25 de abril de 2014

jQuery $(document).ready no siempre funciona con updatepanel

Si estás trabajando con UpdatePanel y jQuery puede ser que acabes teniendo un problema cuando cargues la página parcialmente.


Partimos de lo siguiente:


En la carga inicial de la página realizamos con jQuery algunas acciones mediante el $(document).ready().


Comprobamos que cuando ejecutamos la página esto funciona correctamente.


Cuando hacemos una carga parcial de la página dentro de un UpdatePanel entonces no se ejecutará la función ready() de jQuery ya que el DOM se ha creado en la carga inicial.


Si queremos que se produzcan las mismas acciones en la carga parcial usaremos el siguiente código:




$(document).ready(function()
// Nuestro código al incializar la página (DOM cargado)
);

var prm = Sys.WebForms.PageRequestManager.getInstance();

prm.add_endRequest(function()
//Volver a escribir nuestro código al realizar una carga parcial de la página con UpdatePanel
);



jQuery $(document).ready no siempre funciona con updatepanel

jueves, 24 de abril de 2014

Copiar un proyecto de un repositorio remoto con Visual Studio 2013 y Git

Si necesitas empezar a trabajar en un proyecto de equipo que haya comenzado entonces necesitarás copiarte el proyecto en un repositorio local.


Para ello lo primero que debes hacer es añadir, si no lo tienes ya, un repositorio local donde vincularás los ficheros del proyecto. Para crear un repositorio debes ir a la ventana del Team Explorer dentro de Visual Studio 2013 y pulsar el botón con forma de enchufe “Conectar con proyectos de equipo” (vale simplemente con abrir el Visual Studio, no es necesario utilizar ningún proyecto creado).


Git Visual Studio Repositorio Remoto


Una vez creado el repositorio, debes seleccionarlo y después pulsar la opción de clonar:


Git Visual Studio Repositorio Remoto 2


En este punto Visual Studio te pemitirá introducir la url donde está ubicado el repositorio remoto (en este punto puedes meter un repositorio creado con BitBucket o GitHub). Además podrás seleccionar el repositorio local aunque aparecerá por defecto el repositorio seleccionado anteriormente que hemos creado en el punto anterior.


Cuando tengas todo preparado pulsarás el botón “Clonar” y obtendrás los ficheros del repositorio remoto a local.


Git Visual Studio Repositorio Remoto 3


Una vez haya terminado de recibir todos los ficheros entonces podremos ir a la ruta local de nuestro repositorio y abrir el proyecto que tendremos añadido directamente al control del código fuente. Ya podremos trabajar con él.



Copiar un proyecto de un repositorio remoto con Visual Studio 2013 y Git

lunes, 21 de abril de 2014

Recorrer un array con jQuery

Para recorrer un array con jQuery podemos utilizar el comando .each(). Su definición es:


jQuery.each( collection, callback(indexInArray, valueOfElement) )


Es decir pasamos como primer parámetro el array y como segundo una función que recibe como el índice del elemento recorrido y su valor.


Un ejemplo de su uso:




var obj = one: 1, two: 2, three: 3, four: 4, five: 5 ;

jQuery.each( obj, function( i, val )
$( "#" + i ).append( document.createTextNode( " - " + val ) );
);


En el ejemplo anterior se crearían los siguientes textos:


-1

-2

-3

-4

-5


…colocados respectivamente dentro de elementos dentro del DOM cuyos identificadores sean: “one”, “two”, “three”, etc…



Recorrer un array con jQuery

viernes, 18 de abril de 2014

Diccionario Informático: CRUD

En informática CRUD es el acrónimo de Crear, Obtener, Actualizar y Borrar (del original en inglés: Create, Read, Update and Delete). Se usa para referirse a las funciones básicas en bases de datos o la capa de persistencia en un software.




Diccionario Informático: CRUD

jueves, 17 de abril de 2014

Consumir una API con jQuery y AJAX

En este post intentaremos aprender a consumir una API con jQuery y AJAX.


Nota: en el ejemplo que vamos a desarrollar partimos con que nuestro servicio API se encuentra en la misma web donde vamos a desarrollar el cliente.


Partimos también con que existen dos métodos en la API: obtención de una lista de todos los productos (URI: ”/api/products”) y seleccionar un producto por un identificador (URI: ”/api/products/id“). La URI podrá cambiar dependiendo donde se ubique el servicio… en muchos casos puede ser del tipo “http://…”


Usaremos jQuery para realizar llamadas AJAX y actualizar la página con los resultados.


Empezamos por crear nuestro archivo vacío HTML. En él escribiremos lo siguiente:




<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Product App</title>
</head>
<body>

<div>
<h2>All Products</h2>
<ul id="products" />
</div>
<div>
<h2>Search by ID</h2>
<input type="text" id="prodId" size="5" />
<input type="button" value="Search" onclick="find();" />
<p id="product" />
</div>

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
<script>
var uri = 'api/products';

$(document).ready(function ()
// Send an AJAX request
$.getJSON(uri)
.done(function (data)
// On success, 'data' contains a list of products.
$.each(data, function (key, item)
// Add a list item for the product.
$('<li>', text: formatItem(item) ).appendTo($('#products'));
);
);
);

function formatItem(item)
return item.Name + ': $' + item.Price;


function find()
var id = $('#prodId').val();
$.getJSON(uri + '/' + id)
.done(function (data)
$('#product').text(formatItem(data));
)
.fail(function (jqXHR, textStatus, err)
$('#product').text('Error: ' + err);
);

</script>
</body>
</html>


Nota: Existen muchas maneras de obtener jQuery, en este caso lo obtenemos de un recurso compartido en Internet (http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js)


Obtener la lista de productos


Para obtener la lista de productos se envía una petición HTTP (GET) a la uri donde se encuentra el servicio API. (/api/products).


La función de jQuery getJSON envía una petición asíncrona AJAX. La respuesta esperará por tanto un array de objetos JSON.  La función “done” especifica que la respuesta ha llegado. Cuando llegue la respuesta actualizaremos el DOM con la información que hemos recibido.




$(document).ready(function ()
// Send an AJAX request
$.getJSON(apiUrl)
.done(function (data)
// On success, 'data' contains a list of products.
$.each(data, function (key, item)
// Add a list item for the product.
$('<li>', text: formatItem(item) ).appendTo($('#products'));
);
);
);


Obtener un elemento pasando un identificador


Para obtener un producto por un un identificador, enviaremos un petición HTTP GET a “/api/products/id“, donde id es el identificador de producto.




function find()
var id = $('#prodId').val();
$.getJSON(apiUrl + '/' + id)
.done(function (data)
$('#product').text(formatItem(data));
)
.fail(function (jqXHR, textStatus, err)
$('#product').text('Error: ' + err);
);




Consumir una API con jQuery y AJAX

miércoles, 16 de abril de 2014

Programar una API con ASP.NET

Como sabemos el protocolo HTTP no sirve únicamente para servir páginas Web sino que también puede actuar como APIs que exponen servicios y datos. Estos servicios pueden ser consumidos por una gran cantidad de clientes como pueden ser navegadores, aplicaciones de escritorio, etc.


Crear un proyecto ASP.NET Web API


Centrándonos un poco más en ASP.NET, con Visual Studio 2013 existe la posibilidad de crear de una manera extremadamente fácil un proyecto API. Se hará a través de una plantilla.


Web API

Nuevo proyecto Web


Web API 2

Asignar plantilla Web API a la creación del proyecto


Gracias a esta plantilla Visual Studio nos creará automáticamente un esqueleto que nos permitirá poder añadir elementos de servicio que darán funcionalidad a nuestra API. En la anterior imagen creamos un proyecto vacío pero si nos fijamos también hemos marcado más abajo que queremos que nos añada los directorios y las referencias necesarias en el proyecto.


Como siempre las cosas se pueden hacer de distintas maneras… en este caso también se puede afrontar la creación de la API con MVC. En nuestro caso continuaremos sin utilizar MVC.


Añadir  un modelo


A continuación añadiremos un modelo. El modelo es un objeto que representa los datos de tu aplicación. ASP.NET Web API puede serializar automáticamente tu modelo a JSON, XML o cualquier otro formato y entonces escribir los datos serializados dentro del cuerpo de la respuesta HTTP. Además el cliente siempre puede indicar que formato quiere fijando la cabecera en la petición del servicio.


En este ejemplo añadiremos un modelo que represente un producto. Para ello haremos click derecho encima de la carpeta Models y añadiremos una clase.


Web API Modelo


Nombraremos la clase como “Product” y escribiremos el siguiente código:



namespace ProductsApp.Models

public class Product

public int Id get; set;
public string Name get; set;
public string Category get; set;
public decimal Price get; set;



Añadir un controlador


En Web API, un controlador es un objeto que maneja peticiones HTTP. Añadiremos un controlador que devuelva una lista de productos o un único producto especificado por un Identificador.


Para añadir un controlador haremos click derecho sobre el directorio “Controllers” dentro de la solución y seleccionaremos “Controller”.


Web API Controlador


En la nueva ventana elegiremos Web API Controller – Empty. Pulsaremos añadir.


Web API Controlador 2


Le podremos llamar “ProductsController” por ejemplo. Insertaremos el siguiente código dentro de este fichero:




using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;

namespace ProductsApp.Controllers

public class ProductsController : ApiController

Product[] products = new Product[]

new Product Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 ,
new Product Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M ,
new Product Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M
;

public IEnumerable<Product> GetAllProducts()

return products;


public IHttpActionResult GetProduct(int id)

var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)

return NotFound();

return Ok(product);





Si nos fijamos existen 2 métodos: GetAllProducts y GetProduct. Gracias a ASP.NET Web API podremos acceder a cada uno de estos métodos a través de las siguientes URIs: /api/products y /api/products/id.


Como vemos es muy sencillo programar una API con ASP.NET. En otro post hablaremos de cómo se puede consumir un servicio de este tipo con AJAX y jQuery.



Programar una API con ASP.NET

sábado, 12 de abril de 2014

Error en owin al renombrar proyectos

Si renombramos un proyecto o varios de ellos en una aplicación web y estamos utilizando Owin es posible que aparezca el siguiente error:


The following errors occurred while attempting to load the app.

- The OwinStartup attribute discovered in assembly ‘x’ referencing startup type ‘x.Startup’ conflicts with the attribute in assembly ‘y’ referencing startup type ‘y.Startup’ because they have the same FriendlyName ”. Remove or rename one of the attributes, or reference the desired type directly.

To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of “false” in your web.config.

To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config.


Este error se suele producir porque existen dos ensamblados cargados en nuestra carpeta bin de la solución que contiene una clase startup. En la ejecución de la aplicación asp.net no sabe resolver cual de las dos clases debe ejecutar y de ahí el error.


La solución es ir a la carpeta bin y borrar la dll antigua que ya no es necesaria.



Error en owin al renombrar proyectos

lunes, 31 de marzo de 2014

Recargar página automáticamente mediante la intrucción Meta refresh

Igual no es una instrucción muy conocida (o al menos yo no la conocía hasta ahora) pero existe una opción en html para indicar al navegador que la página se refresque pasado un cierto número de segundos.


Esta instrucción se representa mediante la etiqueta meta y se debería insertar dentro de la etiqueta <head> aunque en algunos casos pueda funcionar fuera de ella:




...

<header>

<META http-equiv=refresh content=10>

...


En el ejemplo anterior le estamos diciendo que la página se refresque automáticamente cada 10 segundos.


Existe la opción de indicarle al navegador que pasados un cierto número de segundos debe redirigir a una url especificada. En el siguiente ejemplo haremos que el navegador vaya a la url: “pagina.com” pasados 5 segundos.




<meta http-equiv="refresh" content="5; url=http://pagina.com/">


En este otro ejemplo que aparece a continuación le indicamos que redirija a la url “pagina.com” inmediatamente asignando a content el valor 0.




<meta http-equiv="refresh" content="0; url=http://pagina.com/">


Esta es una manera bastante elegante de recargar página automáticamente únicamente con html. Lógicamente existen otras maneras como pueden ser scripts realizados en javascript, php, asp, etc…



Recargar página automáticamente mediante la intrucción Meta refresh

martes, 25 de marzo de 2014

Hacer un Response de cualquier tipo de contenido dentro de un UpdatePanel

Cuando trabajamos con UpdatePanel en ASP existe la posibilidad de que no se pueda realizar una respuesta de cualquier tipo de contenido sin realizar un postback.


Por ejemplo: creación de un fichero xls o xlsx de Excel.




...

HttpContext.Current.Response.ContentType = "application/ms-excel";

...


Si el control que hace de trigger se encuentra dentro del mismo updatepanel es muy posible que sea necesario indicar en el script que dicho control desencadenará el evento.




<asp:UpdatePanel runat="server" ID="upPanel">

<Triggers>

<asp:PostBackTrigger ControlID="btnTrigger" />

</Triggers>

...

</asp:UpdatePanel>



Hacer un Response de cualquier tipo de contenido dentro de un UpdatePanel

jueves, 6 de marzo de 2014

Notificar una excepción manualmente a ELMAH

Si trabajamos con ELMAH y realizamos nuestro propio control de errores será necesario notificarle que queremos que guarde esa excepción controlada. Lo haremos con:




ErrorSignal.FromCurrentContext().Raise(ex);



Notificar una excepción manualmente a ELMAH

domingo, 2 de marzo de 2014

Como crear un Theme en ASP NET

Para crear un Tema o Theme en Visual Studio debemos hacer click derecho sobre el proyecto web y añadir la carpeta de ASP.NET App_Themes . Nos pedirá un nombre, le daremos el nombre MainTheme por ejemplo.


Una vez creado este directorio especial podemos añadirle dentro de sí un nuevo item de extensión .Skin.


Lo último que nos queda es especificar en el web.config la theme que usará el sitio por defecto.




<configuration>
<system.web>
<pages theme="MainTheme">

</pages>

</system.web>

</configuration>


Ya estará funcionando nuestro tema, solo quedaría definir en nuestro skin las propiedades de cada control.



Como crear un Theme en ASP NET

viernes, 28 de febrero de 2014

Crear un botón de ASP NET con Glyphicon

Si con Bootstrap queremos utilizar un botón que tenga un icono de Glyphicon tenemos que olvidarnos del clásico asp:button y utilizar asp:linkbutton de la siguiente manera:




<asp:LinkButton runat="server" Text="<span class='glyphicon glyphicon-remove'></span>" CssClass="btn btn-default btn-xs" />


Lo que hacemos es darle una clase al linkbutton de Boostrap y dentro del text (innerhtml) la etiqueta span y su contenido.


No olvides que debes de tener los ficheros de css necesarios para que esto funcione, o sea bootstrap.css o bootstrap.min.css.



Crear un botón de ASP NET con Glyphicon

jueves, 27 de febrero de 2014

martes, 25 de febrero de 2014

Modelo y Base de Datos con Identity en ASP NET

Con la versión 4.5 de .NET Framework se ha incorporado la autenticación basada en Identity. Esto ya lo hablamos en pasadas entradas, ahora vamos a verlo un poquito más a fondo.


Con Identity se crean las siguientes tablas:


  • AspNetRoles

  • AspNetUserClaims

  • AspNetUserLogins

  • AspNetUserRoles

  • AspNetUsers

En estas tablas se guarda toda la información relacionada con los usuarios. Es en la tabla AspNetUsersr donde  se guardan los siguientes campos:


  • Id

  • UserName

  • PasswordHash

  • SecurityStamp

  • Discriminator

En la siguiente imagen se muestra la estructura de tablas y los campos de la tabla AspNetUsers:


Tablas con Identity en ASP.NET 4.5


Ya entrando en el código, si has generado el proyecto web con una de las plantillas que ofrece Visual Studio 2013 verás que en la carpeta “Models” se ha creado un archivo llamado “IdentityModels.cs”. En este fichero existen varias clases que definen la funcionalidad de Identity en la aplicación. Las clases son:


  • ApplicationUser. Es la entidad Usuario de aplicación. Hereda de “IdentityUser” e inicialmente está vacía aunque podemos meterle las propiedades que deseemos para personalizar nuestro modelo de usuario (http://go.microsoft.com/fwlink/?LinkID=317594). Si nos fijamos en la clase de la que hereda contiene las siguientes propiedades que se mapean a la base de datos: Id, PasswordHash, SecurityStamp, UserName así como las colecciones que relacionan con las demás tablas.

Clase IdentityUser


  • ApplicationDbContext. Es la clase que maneja el contexto Entity Framework con la base de datos. De hecho en su constructor coge el connectionstring del web.config para su conexión con la base de datos en este caso “DefaultConnection”.

Clase ApplicationDbContext


  • UserManager. Es una clase que gestiona operaciones típicas de usuarios con la base de datos. Hereda de “UserStore” y tiene diversos métodos de creación y borrado de usuarios, adicción y eliminación de roles por usuario, búsqueda por nombre o id y muchos más. También tiene gran parte de estos métodos en su modalidad asíncrona. Sin embargo desde aquí no es posible obtener todos los usuarios.

  • IdentityHelper. Esta clase estática situada fuera del espacio de nombres “Models”se encarga de sincronizar la base de datos en los registros de usuarios con el comportamiento de la aplicación en lo que se refiere a la autenticación. Cada vez que un registro de un usuario se efectúa correctamente pasará por IdentityHelper para insertarlo en la base de datos y posteriormente autenticarlo en la aplicación.

Después de analizar todo este rollo vamos a ver como podríamos obtener todos los usuarios con Identity. Si utilizamos directamente el contexto “ApplicationDbContext” accederemos a todos los usuarios mediante su propiedad “Users”:




IList<ApplicationUser> users = context.Users.ToList();



Modelo y Base de Datos con Identity en ASP NET

lunes, 24 de febrero de 2014

Unobtrusive validation en ASP NET 4.5

Unobstrusive validation (algo así como validación no obstrusiva) es una nueva característica introducida en ASP.NET 4.5. En un escenario normal cuando usamos un validador para validar cualquier control en el lado cliente se genera cierto código javascript automáticamente que se encarga de realizar esa funcionalidad.


Con la característica Unobstrusive Validation no se genera este código javascript pero para realizar la validación utiliza los atributos HTML5 data-*.


Cuando se crea un nuevo proyecto web con Visual Studio 2013 esta característica está por defecto habilitada.


Para manejar el valor en el que se establecerá esta característica podremos hacerlo de dos formas:


  • Dentro de <appSettings> en web.config:

Habilitado:


<add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms"/>

Deshabilitado:


<add key="ValidationSettings:UnobtrusiveValidationMode" value="None"/>

  • En Application_Start dentro del global.asax:


void Application_Start(object sender, EventArgs e)

//Habilitar característica Unobtrusive Validation
ValidationSettings.UnobtrusiveValidationMode = UnobtrusiveValidationMode.WebForms;
//Deshabilitar característica Unobtrusive Validation
ValidationSettings.UnobtrusiveValidationMode = UnobtrusiveValidationMode.None;



Unobtrusive validation en ASP NET 4.5

sábado, 22 de febrero de 2014

Cambiar idioma a Firefox

Para cambiar el idioma a Firefox debemos ir a:


Herramientas -> Opciones -> Contenido


Abajo aparece la opción de idiomas donde podemos gestionar fácilmente los idiomas aceptados por el navegador.


Cambiar idioma a Firefox u otros navegadores es útil para desarrolladores que quieren probar webs que utilicen un idioma u otro en función del idioma del usuario.



Cambiar idioma a Firefox

jueves, 20 de febrero de 2014

Key o clave en Entity Framework Code First

Al crear un proyecto con visual studio 2013 que utilice Entity Framework Code First me asaltó la duda de por qué en el modelo no existía en casi ninguna clase la DataAnnotation [Key] que establece que propiedad será la encargada de guardar la clave de la tabla.


Primero hay que indicar que en Entity Framework es absolutamente necesario que cada entidad contenga una clave primaria. En el caso de que no se establezca ninguna clave el generador de la base de datos dará un error en tiempo de ejecución.


Sin embargo si Entity Framework no encuentra la DataAnnotation [Key] irá a buscar una propiedad de la clase que contenga la palabra “Id” (no es case-sensitive) y la asignará automáticamente.




public class Movie


[Required, StringLength(100), Display(Name = "Name")]
public string MovieName get; set;
public int Id get; set;



En el ejemplo anterior a la hora de generar la tabla Movie, Entity Framework entenderá que la propiedad “Id” será la encargada de ser la clave.



Key o clave en Entity Framework Code First

miércoles, 19 de febrero de 2014

Entity Framework Code First

Entre las muchas sorpresas que Microsoft nos viene dando con .NET 4.5 está el progreso que ha hecho la tecnología de Entity Framework esforzándose para que el desarrollador se olvide cada vez más de SQLServer y se pueda centrar en lo que es puramente su trabajo: programar (que no es poco).


Esta última versión (Entity Framework 6) permite utilizar el paradigma de programación Code First (Primero el código). Es cierto que en anteriores versiones se podía utilizar esta técnica pero puedo asegurar que era bastante más complicado que ahora.


¿En qué consiste code first?

Code First te permite primero crear el modelo de datos como clases para posteriormente migrarlo a un sistema de gestión de base de datos. Las clases que se definen para crear el esquema de datos se llaman Entidades o Entity Classes.


Cada propiedad de una clase le corresponde una columna en una tabla equivalente de la base de datos. A estas entidades también se les pueden añadir métodos y funciones.



Entity Framework Code First

martes, 18 de febrero de 2014

Aplicaciones web contra Sitios Web en visual studio

Desde que recuerdo en Visual Studio siempre ha habido dos maneras de crear webs llamadas:


  • Aplicaciones Web

  • Sitios Web

En Visual Studio 2013 sigue existiendo está filosofía pero… ¿en qué se diferencian las aplicaciones web de los sitios web?


Existen ventajas y desventajas en cada una de las dos implementaciones.


En aplicaciones web:


  • Permite utilizar la característica “Editar y continuar” del depurador. Esta característica es un problema en Visual Studio 2010 instalado en Sistemas Operativos de 64 bits ya que no funcionaba correctamente. En Visual Studio 2013 funciona correctamente.

  • Permite ejecutar pruebas unitarias en los codebehind de los aspx.

  • Puedes crear referencias a todos los archivos de código de la aplicación.

  • Es posible crear dependencias de proyecto entre varios proyectos web.

  • El compilador puede crear un ensamblado único para todo el sitio.

  • Puedes controlar la versión y nombre de ensamblado.

  • Es posible evitar situar código fuente en producción.

En sitios web:


  • No es necesario compilar el proyecto para implementarlo.

  • Es posible actualizar los archivos en producción editándolos directamente.

  • No existe un archivo de proyecto (.csproj o .vbproj).

  • La ejecución de una página individual no requiere la compilación correcta de todo el sitio web al completo. (En un proyecto de aplicación Web, no pueden existir errores de compilación en cualquier parte del sitio ya que de esta manera no generaría el ensamblado)

Resumiendo y desde mi punto de vista, los sitios web se utilizan para proyectos simples que no requieren de una gran infraestructura de código ni un gran número de dependencias. En cambio para proyectos de gran envergadura y que necesiten cierta arquitectura (3 capas por ejemplo) es mejor utilizar una implementación de proyecto Web.



Aplicaciones web contra Sitios Web en visual studio

domingo, 16 de febrero de 2014

Bundling y Minification en ASP.NET 4.5

Bundling es una nueva característica dentro de ASP.NET 4.5 que hace fácil combinar diversos ficheros en un único fichero. Esto es muy recomendable porque acelera sustancialmente la carga de la página y con ello mejora el rendimiento de la aplicación.


No hay que confundir bundling con minification, pero… ¿qué signfica Minification? Seguro que os habéis preguntado en alguna ocasión por qué en muchos ficheros que os descargáis por la red existen dos ficheros uno con extensión min.css o min.js y otro sin él. El fichero min es básicamente el mismo pero en él se eliminan los espacios en blanco no significativos, comentarios y se acortan los nombres de las variables. El objetivo final de esto es acortar el tiempo de carga de estos ficheros.


Los ficheros donde se utilizan estas técnicas son archivos javascript y css.


Bundling y minification se habilitan o deshabilitan en base al valor de la propiedad debug dentro del elemento compilation del web.config.


Si debug=”true” entonces el agrupamiento y la minificación estarán deshabilitadas. Es lógico, si queremos depurar la aplicación y queremos que el código sea legible necesitaremos distintos archivos y líneas de código, no un “tocho” de código dentro de una misma línea.


Si debug=”false” entonces se habilitarán estas dos características.


En un proyecto web creado con plantilla con Visual Studio podremos observar que existe un fichero llamado startup.cs gestionado por OWIN que se ejecuta al iniciar la aplicación.En este fichero se llama a un fichero de configuración de bundling llamado BundleConfig.cs (dentro del directorio App_Start) que se encarga de asignar los Bundling y Minification.


 


 


 



Bundling y Minification en ASP.NET 4.5

sábado, 15 de febrero de 2014

Autenticación en Visual Studio 2013

En Visual Studio 2013 han introducido una manera sencilla para establecer el tipo de autenticación que usará la aplicación web.


autenticacion_visual studio 2013


Estos son los métodos de autenticación en Visual Studio 2013


  • Sin autenticación

  • Cuentas de usuario individuales: usuarios guardados en base de datos, o cuentas de Facebook, Twitter, Google, Microsoft o de otros proveedores.

  • Cuentas profesionales: Active Directory, Windows Azure Active Directory y Office 365.

  • Autenticación de Windows

Como podemos comprobar la autenticación de aplicaciones de Visual Studio 2013 ha cambiado notablemente, este aspecto está influido por la nueva filosofía que ha tomado Microsoft para su integración de aplicaciones web en un entorno más actual y no completamente atado a tecnologías propias de Microsoft.



Autenticación en Visual Studio 2013

viernes, 14 de febrero de 2014

OWIN: Otra novedad en Visual Studio 2013

Open Web Interface for .NET (OWIN) define una nueva capa de abstración entre el servidor web y una aplicación web. De este modo OWIN permite a las aplicaciones que no les importe en que host esté hospedado. Por ejemplo una aplicación web se puede hospedar en IIS o en un proceso personalizado.


Esta tecnología se conoce también como el proyecto Katana y se inspira en otras tecnologías del estilo node.js.


El problema que intenta solucionar OWIN es desacoplar la dependencia que tenían las aplicaciones ASP.Net con el servidor IIS introduciendo una capa que maneje las peticiones Http.


Sin Open Web Interface for .Net:


Sin OWIN


Con Open Web Interface for .Net:


Con OWIN



OWIN: Otra novedad en Visual Studio 2013

jueves, 13 de febrero de 2014

Razor en ASP NET

Desde la aparición de Visual Studio 2010 en las aplicaciones MVC se utiliza Razor pero… ¿qué es Razor en ASP Net?


Razor no es un lenguaje de programación sino que es un código insertado en ficheros .cshtml (c#) o .vbhtml (visual basic) que interpreta el servidor. Es decir, Razor es un marcado que “escapa” el código html para utilizar el que es en realidad el verdadero lenguaje de programación (C# o Visual Basic). El caracter con el que “escapa” el código html es @.


Cuando conocí Razor la primera idea que me vino a la cabeza fue que esto llevaba inventado mucho tiempo pero con otros nombres: asp clásico, php incluso en asp.net se puede “escapar” el código con las etiquetas <%%>. Todo esto es cierto pero la ventaja fundamental que ofrece Razor es su simplicidad que se traduce posteriormente en una mayor legibilidad del código.


Un ejemplo:


ASP.Net Sin Razor:


sin_razor


ASP.Net con Razor:


con razor


En mi opinión es muy fácil de aprender, se mejora la legibilidad y más sencillo de escribir. Además en Visual Studio funciona el Intellisense.



Razor en ASP NET

miércoles, 12 de febrero de 2014

Visual Studio 2013 apuesta por Bootstrap

Del mismo modo que Microsoft se decantó por dar soporte a jquery dentro de sus plantillas de proyectos de Visual Studio 2010 ahora podemos comprobar que con Visual Studio 2013 existen plantillas para desarrollar con bootstrap.


Creo que se han dado cuenta de que no podían prescindir de un framework que hiciera más fácil el diseño web adaptable (responsive design) indispensable hoy en día como todos bien sabemos.


Siempre podemos utilizar Foundation (el gran competidor de bootstrap) aunque yo no lo recomendaría por dos razones. La primera razón es que considero que hay que confiar en las decisiones de Microsoft, ellos son los que mejor conocen su framework y seguro que lo han valorado en su día. La segunda razón, sufrida en mis propias carnes, es que he comprobado que algunos controles asp no se llevan muy bien con Foundation.



Visual Studio 2013 apuesta por Bootstrap

martes, 11 de febrero de 2014

Menús con scroll

En este post explicaré la forma de hacer menús con scroll típicos en sitios web de una sola página.


Antes de nada decir que existen unos cuantos plugins de jquery para realizar webs de una sola página en el que viene implementado ya un menú de este tipo. Por ejemplo son muy conocidos Smint y CoolKitten. En el ejemplo de este post utlizaremos jquery waypoints.


Lo primero que debemos hacer es crear las distintas secciones a los que se dirigirán los enlaces del menú.




...

<div id="seccion_1">...</div>

<div id="seccion_2">...</div>

<div id="seccion_3">...</div>

...


Posteriormente implementaremos el menú con enlaces a cada uno de las secciones establecidas anteriormente.




<div id="menu">

<ul>

<li><a id="menu_seccion1" href="#seccion_1">ir a seccion 1</a></li>

<li><a id="menu_seccion2" href="#seccion_2">ir a seccion 2</a></li>

<li><a id="menu_seccion3" href="#seccion_3">ir a seccion 3</a></li>

</ul>

</div>


Este menú necesitamos dejarlo fijo en algún punto para que sea visible durante todo el scroll de la página. Por ejemplo en nuestro caso lo situaremos debajo de la pantalla. Para ello usaremos css y la propiedad position fixed:




#menu



position:fixed;

bottom:0;




Con todo esto y utilizando únicamente html y css podemos crear un menú con scroll. El problema es si queremos que los elementos del menú se activen o desactiven dependiendo de que sección nos encontremos. Para hacerlo ya necesitaremos javascript. Con jquery y jquery waypoints podemos manejar eventos que se produzcan cuando el usuario se encuentre en una u otra sección de la página. No olvideis importarlo a vuestra página.




$('#seccion_1') .waypoint(function(direction)

//esto se ejecutará cuando el usurio esté dentro de la sección 1

alert('esto se ejecutará cuando el usurio esté dentro de la sección 1');



Con esto, jquery y un poco de imaginación podemos hacer casi todo. Entre otras cosas cambiar la clase css de cualquier elemento del menú cuando se llegue a la sección indicada.




$('#seccion_1') .waypoint(function(direction)

$('#menu_seccion1').addClass('menu_active');





Menús con scroll

domingo, 9 de febrero de 2014

Imagen en un input type submit

Si queremos poner una imagen en un input type submit es tan sencillo como no poner type=”submit” sino type=”image”. El form donde esté metido el input lo tomará como un botón de enviado del formulario.




<form action="enviar_form.php">

<input type="text" name="nombre"/>

<input title="boton enviar" alt="boton enviar" src="img/mi_imagen.jpg" type="image" />

</form>

</form>



Imagen en un input type submit

sábado, 8 de febrero de 2014

Ajustar background image con css

Es posible ajustar background image con css 3 gracias a la propiedad background-size.


El problema que existe con la propiedad background-image de css es que la resolución de la imagen no se adapta al tamaño de la capa y por tanto tampoco de cualquier otro elemento heredando el problema de las diversas resoluciones de pantalla para todos los tipos de dispositivos.


La propiedad background-size pretende solucionar este problema. Como gran parte de las propiedades de css3 cada navegador usa su propia etiqueta para aplicarlo en su renderizado.




.capa_imagen_ajustada



background-image: url('img/fondo.jpg');

-moz-background-size: 100% 100%; /*Firefox 3.6*/

-o-background-size: 100% 100%; /*opera*/

-webkit-background-size: 100% 100%; /*Safari*/

background-size: 100% 100%; /*estandar css3*/

-moz-border-image: url('img/fondo.jpg') 0; /*Firefox 3.5*/





Ajustar background image con css

jueves, 6 de febrero de 2014

Bancos de imagenes gratuitos

En este post iré actualizando aquellas webs que sirvan como bancos de imagenes gratuitos.


  • Unsplash, es una web con fotografías de una altísima calidad. En esta web no busques iconos o algo por el estilo ya que son fotografías tomadas por profesionales de la imagen.

  • Foter, web con  un poco de todo. Incorpora un buscador que a veces no sirve ya que no encuentras lo que necesitas. Imagenes de buena, mediana y mala calidad.

Iré metiendo más según vaya probando por internet.. por favor si conoces alguno que sea interesante no dudes en dejar tu comentario.


Gracias.



Bancos de imagenes gratuitos

Bancos de imagenes gratuitos

En este post iré actualizando aquellas webs que sirvan como bancos de imagenes gratuitos.


  • Unsplash, es una web con fotografías de una altísima calidad. En esta web no busques iconos o algo por el estilo ya que son fotografías tomadas por profesionales de la imagen.

  • Foter, web con  un poco de todo. Incorpora un buscador que a veces no sirve ya que no encuentras lo que necesitas. Imagenes de buena, mediana y mala calidad.

Iré metiendo más según vaya probando por internet.. por favor si conoces alguno que sea interesante no dudes en dejar tu comentario.


Gracias.



Bancos de imagenes gratuitos

miércoles, 5 de febrero de 2014

Cambiar src de imagen con jquery

Supongamos que tenemos una imagen como está en nuestro html




<img id="mi_imagen"  src="img/origen_1.jpg"/>


Si queremos cambiar el origen de donde toma la imagen nuestro elemento img podemos utilizar jquery:




$("#mi_imagen").attr("src","img/origen_2.jpg");



Cambiar src de imagen con jquery

martes, 4 de febrero de 2014

Opacidad con css

En este post explicaremos las dos maneras de dar transparencia u opacidad con css.


La manera a utilizar la opacidad dependerá de cómo quieres que se comporten los elementos secundarios. Los elementos secundarios que se encuentren anidados dentro un elemento padre pueden heredar o no esa opacidad.


  • Heredar transparencia a elementos secundarios:



#parent



opacity: .5;
-moz-opacity: .5;
filter:alpha(opacity=5);




  • No heredar la opacidad a elementos secundarios:



#parent



background:rgba(0,0,10,0.5);





Opacidad con css

Scroll lento a secciones de una página mediante enlaces

Quizá ya conozcamos que si estamos en una página que tiene distintas secciones se puede ir a través de un menú o enlaces.


<br /><br />...<br /><br />&lt;div id="seccion_1"&gt;contenido 1&lt;/div&gt;<br /><br />&lt;div id="seccion_2"&gt;contenido 2&lt;/div&gt;<br /><br />...<br /><br />&lt;a href="#seccion_1"&gt;ir a sección 1&lt;/a&gt;<br /><br />&lt;a href="#seccion_2"&gt;ir a sección 2&lt;/a&gt;<br /><br />

La navegación a estos elementos o capas es instantánea. Con jQuery podemos establecer la velocidad con la que se producirá la navegación haciendo un efecto de transición que en muchas ocasiones es visualmente más atractivo.


Lo primero que haremos es importarnos, si no la tenemos ya, nuestra librería de jQuery.


Después para cada elemento que queramos el efecto de animación usaremos este código:


<br /><br />$('a[href=#seccion_1]').click(function (event) <br /><br />event.stopPropagation();<br /><br />var Position = jQuery('[id="seccion_1"]').offset().top;<br />jQuery('html, body').animate( scrollTop: Position , 1100);<br /><br />return false;<br /><br />);<br /><br />

Donde pone 1100 se refiere al tiempo en milisegundos que estará realizando la animación.


Con este valor podemos establecer un scroll lento a secciones de una página.



Scroll lento a secciones de una página mediante enlaces

lunes, 3 de febrero de 2014

Ajustar una capa a la altura de la pantalla con css

Para ajustar una capa a la altura de la pantalla con css es necesario especificar lo primero las alturas a las etiquetas html y body del documento. Y después ajustarle a la capa que queremos establecer el alto.




<html style="height: 100%;">
<body style="height: 100%;">
<div style="height: 100%;">
<p>
Make this division 100% height.
</p>
</div>
</body>
</html>



Ajustar una capa a la altura de la pantalla con css

jueves, 30 de enero de 2014

Globalización en Master Pages

Esta entrada tratará sobre cómo incluir la globalización en Master Pages en asp.net de manera independiente. En el ejemplo utilizaremos código C#.


3 pasos:


Establecer la cultura en el Global.asax

Utilizaremos cookies para guardar el valor de la currentculture en el manejador BeginRequest.




protected void Application_BeginRequest(object sender, EventArgs e)

HttpCookie cookie = Request.Cookies["CultureInfo"];

if (cookie != null && cookie.Value != null)

Thread.CurrentThread.CurrentUICulture = new CultureInfo(cookie.Value);
Thread.CurrentThread.CurrentCulture = new CultureInfo(cookie.Value);

else

Thread.CurrentThread.CurrentUICulture = new CultureInfo("es-ES");
Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES");




Este código lee la información del actual culture y lo establece en la cookie, si la cookie no está establecida entonces pone la cultura por defecto es-ES.


Usar un desplegable para cambiar la cultura en el MasterPage

En nuestro ejemplo usaremos un dropdownlist para cambiar la cultura:




<asp:DropDownList ID="ddlLanguage" runat="server"
OnSelectedIndexChanged="ddlLanguage_SelectedIndexChanged"
AutoPostBack="true">
<asp:ListItem Text="<%$ Resources:Resource, users_Spanish %>" Value="es-ES" />
<asp:ListItem Text="<%$ Resources:Resource, users_French %>" Value="fr-FR" />
</asp:DropDownList>


Manejaremos el evento SelectedIndexChanged en el codebehind:




protected void ddlLanguage_SelectedIndexChanged(object sender, EventArgs e)

//Establecemos la cookie que será usada en el Global.asax
HttpCookie cookie = new HttpCookie("CultureInfo");
cookie.Value = ddlLanguage.SelectedValue;
Response.Cookies.Add(cookie);

//Establecemos la cultura en el currentthread y refrescamos la página.
//Global asax se encargará del siguiente trabajo.
Thread.CurrentThread.CurrentCulture =
new CultureInfo(ddlLanguage.SelectedValue);
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(ddlLanguage.SelectedValue);
Server.Transfer(Request.Path);



En este paso establecemos el valor de la nueva cultura y volvemos a recargar la página mediante el comando Server.Transfer.


Mostrar la cultura actual seleccionada en el dropdownlist en el MasterPage

En este punto solamente queda mostrar cual es la cultura actual seleccionada. Lo haremos con el siguiente código:




protected void Page_Load(object sender, EventArgs e)

if (!Page.IsPostBack)

ddlLanguage.SelectedValue = Thread.CurrentThread.CurrentCulture.Name;





Globalización en Master Pages

miércoles, 29 de enero de 2014

Crear ficheros de recursos de localización en ASP NET

Para crear ficheros de recursos de localización en ASP.NET es necesario tener una carpeta especial de ASP.NET llamada App_GlobalResources o App_LocalResources dependiendo si queremos archivos locales o globales dentro de nuestra aplicación.


Visual Studio te permite crear esta carpeta de una manera sencilla: botón derecho encima de la raíz de tu sitio web y después pinchar en Add->Add ASP.NET Folder->App_GlobarResources.


Recursos Localizacion ASPNET


Una vez hecho esto crearemos nuestro primer fichero de recursos para el idioma neutro, esto es, el que usaremos por defecto para la aplicación. Para hacer este paso pulsaremos botón derecho sobre el directorio que acabamos de crear y añadiremos un archivo de tipo recurso (.resx). El nombre que le demos es el que utilizaremos más tarde para recuperar sus valores. En este caso le llamaremos “res.resx”.


Una vez abierto en este fichero podremos insertar pares de clave y valor donde el valor es la traducción y la clave el identificador unívoco para obtener la traducción.


Podemos crear tantos archivos de recursos como idiomas queramos en nuestro sitio web, para ello podemos copiar el fichero original y pegarlo dentro del mismo directorio: App_GlobalResources pero teniendo en cuenta que el nombre de cada fichero es el que determinará el idioma correspondiente. Por ejemplo para el idioma inglés el nombre del fichero en nuestro caso será “res.en.resx”, en francés sería “res-fr-resx”…


Una vez metida una misma clave en cada fichero con las traducciones correspondientes en la casilla valor podemos empezar a utilizar las traducciones.


Por ejemplo en un fichero aspx:




...

<asp:Literal runat="server" Text="<%$Resources:res,default_bienvenido%>" />

...


Este ejemplo nos escribe un literal y el texto se va a buscarlo a la clave de nombre “default_bienvenido” que exista en el fichero de recursos “res”. Si no encuentra la clave para un fichero de un determinado idioma entonces cogerá la del idioma neutral y si no escribirá directamente la clave.



Crear ficheros de recursos de localización en ASP NET