13 de diciembre de 2010

C#, Manejo de WebException. Error en el servidor remoto: (500) Error interno del servidor.

Recientemente, mientras hacia una petición POST (.Net C#) a una URL determinada, me estaba encontrando con el siguiente error:

WebException, ProtocolError

ex.Message: Error en el servidor remoto: (500) Error interno del servidor.

Error 500

Este es un error genérico que aporta casi nada de información y que por consiguiente poco puedo obtener para solucionar el problema.

Solución Manejo WebException

Para obtener más información de este tipo de error, puedes hacer lo siguiente:

private string Test(HttpWebRequest request)
{
  string responseText = string.Empty;
  try
  {
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
      //...
    }
  }
  catch (WebException wex)
  {
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("ERROR:" + wex.Message + ". STATUS: " + wex.Status.ToString());
 
    if (wex.Status == WebExceptionStatus.ProtocolError)
    {
      var response = ((HttpWebResponse)wex.Response);
      sb.AppendLine(string.Format("Status Code : {0}", response.StatusCode));
      sb.AppendLine(string.Format("Status Description : {0}", response.StatusDescription));
 
      try
      {
       StreamReader reader = new StreamReader(response.GetResponseStream());
        sb.AppendLine(reader.ReadToEnd());
      }
      catch (WebException ex) { throw; }
    }
 
    throw new Exception(sb.ToString(), wex);
  }
  catch (Exception ex) { throw; }
 
  return responseText;
}

Y de esta forma podrás leer la información relacionada al error.

26 de noviembre de 2010

Javascript, Algunas funciones

Hace bastante que no publico nada, y es que los proyectos actuales apenas me dejan tiempo, pero en fin, ya estoy de regreso y hoy compartiré algo muy simple, pero el objetivo de este post es comenzar a escribir las distintas funciones javascript que voy utilizando en el día a día y espero que los lectores también agreguen las suyas.

1. Javacript – Función para eliminar dígitos.

function fnRemoveDigit(text) {
  var newText = text.replace(/[0-9$-]/g, '');
  return newText;
}

2. Javacript – Función para eliminar caracteres distintos de letras.

function fnRemoveNotAlpha(text) {
  return text.replace(/[{-™!-@[-`$-]/g, '');
}

Nota: Eliminará también las letras con acentos, tanto mayúsculas como minúsculas y también los dígitos.

3. Javacript – Función para reemplazar acentos.

function fnReplaceAcents(text){
  return text
    .replace(/(À|Á|Â|Ã|Ä|Å|Æ)/gi,'A')
    .replace(/(È|É|Ê|Ë)/gi,'E')
    .replace(/(Ì|Í|Î|Ï)/gi,'I')
    .replace(/(Ò|Ó|Ô|Ö)/gi,'O')
    .replace(/(Ù|Ú|Û|Ü)/gi,'U')
    .replace(/(Ñ)/gi,'N');
}

4. Javacript – Función para eliminar espacios en blanco delante y detrás (Trim).

function fnTrim(text) {
  return text.replace(/^\s+|\s+$/g, '');
}

5. Javacript – Función para eliminar todos los espacios en blanco.

function fnRemoveSpace(text) {
  return text.replace(/\s/g, '');
}

3 de septiembre de 2010

Arquitectura de Software con Visual Studio 2010 (UML)

Comparto con ustedes estos interesantísimos videos de Clint Edmonson sobre Arquitectura de Software con Visual Studio 2010 (UML), están en ingles y no me gusta publicar nada en la lengua anglosajona, pero creo que si te gusta la Arquitectura estos 9 videos bien valen la pena.

 

  1. How do I…Brainstorm a Project Using Visual Studio 2010.
  2. How Do I…Organize Features Into Use Case Models.
  3. How Do I…Model the Business Domain Using Conceptual Class Diagrams.
  4. How Do I…Capture Business Workflows Using Activity Diagrams.
  5. How Do I…Architect an Application Using a Layer Diagram.
  6. How Do I…Design a Project’s Physical Structure Using a Component Diagram.
  7. How Do I…Sketch Interactions with Sequence Diagrams.
  8. How Do I…Reveal Responsibilities with Class Diagrams.
  9. How Do I…Organize & Manage My Models

 

Si no te gustan demasiado los videos en ingles, podrás seguir una serie parecida a la anterior pero en español, a continuación te dejo el primero de los link de una serie de videos de Francisco Fagas:

  1. VSTS 2010. Casos de uso…

Espero los disfrutes tanto como yo…

22 de agosto de 2010

Encriptar y Desencriptar con C# (Método Simple)

El post de hoy es muy directo, porque cuento con poco tiempo. La idea es la de postear una clase con varios métodos que suelo usar cuando necesito encriptar y desencriptar cadenas de texto.

C# Encriptar y Desencriptar (Clase)

La clase contiene 4 métodos:

  • 2 métodos para encriptar. Uno de ello simple que solo le pasamos el texto a encriptar y usando el resto de los valores por defecto devolvemos el texto ya encriptado. El segundo método hace exactamente lo mismo pero necesita que le pasemos por parámetro todos los datos necesarios para obtener la clave de encriptación.
  • Otros 2 métodos para desencriptar. Uno de ello simple que solo le pasamos el texto encriptado y usando el resto de los valores por defecto devolvemos el texto ya desencriptado. El segundo método hace exactamente lo mismo pero necesita que le pasemos por parámetro todos los datos necesarios para obtener la clave de encriptación.

using System;

using System.IO;

using System.Security.Cryptography;

using System.Text; 

namespace dllObjetosComunes.Utiles

{

  public static class Encriptador

  {

    public static class RijndaelSimple

    {

      #region Encriptar

      /// <summary>

      /// Método para encriptar un texto plano usando el algoritmo (Rijndael).

      /// Este es el mas simple posible, muchos de los datos necesarios los

      /// definimos como constantes.

      /// </summary>

      /// <param name="textoQueEncriptaremos">texto a encriptar</param>

      /// <returns>Texto encriptado</returns>

      public static string Encriptar(string textoQueEncriptaremos)

      {

        return Encriptar(textoQueEncriptaremos,

          "pass75dc@avz10", "s@lAvz", "MD5", 1, "@1B2c3D4e5F6g7H8", 128);

      }  

      /// <summary>

      /// Método para encriptar un texto plano usando el algoritmo (Rijndael)

      /// </summary>

      /// <returns>Texto encriptado</returns>

      public static string Encriptar(string textoQueEncriptaremos,

        string passBase, string saltValue, string hashAlgorithm,

        int passwordIterations, string initVector, int keySize)

      {

        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);

        byte[] saltValueBytes  = Encoding.ASCII.GetBytes(saltValue);

        byte[] plainTextBytes  = Encoding.UTF8.GetBytes(textoQueEncriptaremos);  

        PasswordDeriveBytes password = new PasswordDeriveBytes(passBase,

          saltValueBytes, hashAlgorithm, passwordIterations);

        byte[] keyBytes = password.GetBytes(keySize / 8);

        RijndaelManaged symmetricKey = new RijndaelManaged() {

          Mode = CipherMode.CBC };

        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes,

          initVectorBytes);

        MemoryStream memoryStream = new MemoryStream();       

        CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor,

         CryptoStreamMode.Write);

        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

        cryptoStream.FlushFinalBlock();  

        byte[] cipherTextBytes = memoryStream.ToArray();

        memoryStream.Close();

        cryptoStream.Close();

        string cipherText = Convert.ToBase64String(cipherTextBytes);      

        return cipherText;

      }

      #endregion  

      #region Desencriptar

      /// <summary>

      /// Método para desencriptar un texto encriptado.

      /// </summary>

      /// <returns>Texto desencriptado</returns>

      public static string Desencriptar(string textoEncriptado)

      {

        return Desencriptar(textoEncriptado, "pass75dc@avz10", "s@lAvz", "MD5",

          1, "@1B2c3D4e5F6g7H8", 128);

      }  

      /// <summary>

      /// Método para desencriptar un texto encriptado (Rijndael)

      /// </summary>

      /// <returns>Texto desencriptado</returns>

      public static string Desencriptar(string textoEncriptado, string passBase,

        string saltValue, string hashAlgorithm, int passwordIterations,

        string initVector, int keySize)

      {

        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);

        byte[] saltValueBytes  = Encoding.ASCII.GetBytes(saltValue);

        byte[] cipherTextBytes = Convert.FromBase64String(textoEncriptado);

        PasswordDeriveBytes password = new PasswordDeriveBytes(passBase,

          saltValueBytes, hashAlgorithm, passwordIterations);

        byte[] keyBytes = password.GetBytes(keySize / 8);

        RijndaelManaged symmetricKey = new RijndaelManaged() {

          Mode = CipherMode.CBC };

        ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes,

          initVectorBytes);

        MemoryStream  memoryStream = new MemoryStream(cipherTextBytes);

        CryptoStream  cryptoStream = new CryptoStream(memoryStream, decryptor,

          CryptoStreamMode.Read);

        byte[] plainTextBytes = new byte[cipherTextBytes.Length];

        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0,

          plainTextBytes.Length); 

        memoryStream.Close();

        cryptoStream.Close();

        string plainText = Encoding.UTF8.GetString(plainTextBytes, 0,

          decryptedByteCount);

        return plainText;

      }

      #endregion

    }

  }

} 

 

Artículos Relacionados:

18 de agosto de 2010

jQuery, Teclas de acceso directo

Es un plugin jQuery simple y bastante útil. Suelo usarlo en la mayoría de mis formularios para crear atajos de teclados a distintas funciones, pero veamos un ejemplo.

Imaginemos que deseamos que cuando el usuario presione la tecla enter, se dispare un evento determinado (ej.: lanzar una búsqueda). Pues bien, para ello usaremos el plugin jquery.hotkeys.

Lo primero es Incluir las bibliotecas javascript necesarias:

<script src="jquery-1.3.2.min.js"></script>
<script src="jquery.hotkeys.js"></script>
Hacer uso del plugin hotkeys 

<script>
  $(document).ready(function(){

    $(document).bind('keydown', 'return', function(evt){ 
      alert('Has presionado la tecla return...'); 
      return false; 
    });  
 
  });
</script>

Y ya está, al estar en el formulario si presionas la tecla enter (return) mostraremos un alert().

Si estas pensando en usarlo no dejes de visitar el sitio oficial.

1 de julio de 2010

IIS 7, Habilitando Compresión de Respuesta

Hoy quiero comentarles sobre la posibilidad que tenemos en IIS para comprimir las páginas servidas. Al usar esta opción podremos disminuir considerablemente el trafico de RED entre nuestro servidor y los navegadores WEB clientes.

Para analizarlo me he basado en una página de consulta de disponibilidad de vuelos; como veremos en las imágenes de abajo, paso de recibir 1 546KB a recibir solo 301KB, menos del 20% del valor original, optimizando el ancho de banda consumido en más de un 80%.

Compresion NO

Compresion SI

La primera imagen es el resultado de consultar la página (AereoBuscador) sin haberle habilitado la compresión en el IIS. Y el tamaño de la respuesta obtenida es de: 1 546 KB.

La segunda imagen corresponde a la misma página (AereoBuscador) pero en esta ocasión con la compresión activada en el IIS. Y la respuesta es de  301 KB.
El 19.5% del valor anterior.

 

Pasos para Activar la Compresión en el IIS 7

Para activar esta opción basta con abrir IIS y localizar el sitio al que le queremos habilitarle la compresión, y una vez situados en el sitio abrimos la opción de compresión (figura de la izquierda) y marcamos los check (imagen de la derecha)

Compresion Step 1 Compresion Step 2

Así de fácil...

Nota: He de puntualizar que la compresión dinámica, aunque por un lado mejora el consumo de ancho de banda, también consume más procesador, con lo que si no se usa en la proporción adecuada puede reducir el rendimiento global del servidor.

24 de junio de 2010

Como evitar Cache de Página en el Explorador (IE, Firefox…)

Si estas desarrollando con ASP.NET y quieres evitar que el explorador almacene en Caché una determinada página Web, tienes varias alternativas para lograrlo, a continuación expongo como evitar el almacenamiento en caché mediante programación.

Cache de Página mediante Programación

En el Page_Load de la página en cuestión colocar el siguiente código (cualquiera de las 2 líneas valdría)

Response.Cache.SetCacheability(HttpCacheability.ServerAndNoCache);
Response.Cache.SetCacheability(HttpCacheability.NoCache);

Cada vez que se haga clic en un botón hacia delante o hacia atrás del explorador, o cualquier evento que genere un POSTBACK, se solicitará al servidor una nueva versión de la página.

Nota: Este mismo resultado (almacenamiento de página en caché) podemos lograrlo de forma declarativa usando la directiva OutputCache. Ej:

<%@ OutputCache Duration="120" VaryByParam="None"%>

13 de junio de 2010

Enum, Attribute To List

Hace unos meses atrás escribí un artículo inicial sobre Enumeraciones y algunos ejemplos básicos. Hoy pretendo continuar aquel post, y veremos los siguientes aspectos:

  1. Usar atributos en Enumeraciones.
  2. Método para recuperar el atributo de un determinado valor de la enumeración (GetDescripcion).
  3. Método para recuperar una lista de todos los elementos de la Enumeración (GetValoresDescripciones).

El objetivo de ambos métodos extensores es poder hacer lo siguiente:

string descripcion = TipoDocumento.Dni.GetDescripcion();

var lstEnumVals = typeof(TipoDocumento).GetValoresDescripciones();

Enum 2 List

Usar Enumeración con Attribute

enum TipoDocumento
{
    [Descripcion("Documento Nacional de Identidad")]
    DNI, // 0

   

    [Descripcion("Número de Identificación de Extranjeros")]

    NIE, // 1

   
    Pasaporte, // 2
   
    [Descripcion("Otros Documentos")]
    Otro = 99
};

Nota: El tipo predeterminado subyacente de las enumeraciones es el int y el primer enumerador tiene valor 0, incrementándose sucesivamente en 1 (A menos que definamos otra cosa).

La enumeración definida, está usando un atributo (Descripcion) que debemos definir en una clase (DescripcionAttribute) como veremos a continuación:

public class DescripcionAttribute : Attribute

{

  public string Descripcion { get; set; } 

  public DescripcionAttribute(string descripcion)

  {

    Descripcion = descripcion;

  }

}

 

Recuperar Attribute de un elemento Enum

public static string GetDescripcion(this Enum valor)

{

  Type type = valor.GetType();

  FieldInfo fieldInfo = type.GetField(valor.ToString());

  var attribs = fieldInfo.GetCustomAttributes(

                  typeof(DescripcionAttribute), false) as DescripcionAttribute[];

  return (attribs == null || attribs.Length == 0) ?

          valor.ToString() : attribs[0].Descripcion;

}

 

Recuperar todos los elementos de una Enum

public static List<KeyValuePair<string, string>> GetValoresDescripciones(

  this Type enumType)

{

  var arrValores = Enum.GetValues(enumType);

  var lstEnumDescripcion = new List<KeyValuePair<string, string>>();

 

  foreach (var valor in arrValores)

  {

    FieldInfo fieldInfo = enumType.GetField(valor.ToString());

   

    var attribs = fieldInfo.GetCustomAttributes(

                    typeof(DescripcionAttribute), false) as DescripcionAttribute[];

    var descripcion = (attribs == null || attribs.Length == 0) ?

                       valor.ToString() : attribs[0].Descripcion;

    lstEnumDescripcion.Add(

      new KeyValuePair<string, string>(valor.GetHashCode().ToString(), descripcion));

  }

  return lstEnumDescripcion;

}

O si prefieres crear el mismo método, pero remplazando el foreach por expresiones LINQ entonces:

public static List<KeyValuePair<string, string>> GetValoresDescripciones(

  this Type enumType)

{

  var arrValores = Enum.GetValues(enumType);

 

  return (from object valor in arrValores

          let fieldInfo = enumType.GetField(valor.ToString())

          let attribs = fieldInfo.GetCustomAttributes(typeof (DescripcionAttribute), false)

                        as DescripcionAttribute[]

          let descripcion = (attribs == null || attribs.Length == 0) ?

                             valor.ToString() : attribs[0].Descripcion

          select new KeyValuePair<string, string>(

                       valor.GetHashCode().ToString(), descripcion)).ToList();

}


Artículos Relacionados:

11 de junio de 2010

Caché Web con CacheDependency en ASP.NET (C#)

Veamos un ejemplo práctico de como implementar el trabajo con Cache en ASP.NET usando HttpRuntime.Cache (System.Web.Caching.Cache).

Si estamos desarrollando una Aplicación Web con ASP.Net y deseamos implementar y usar Caché, este tutorial te será de utilidad. Existen varias soluciones para implementar el trabajo con Caché (AppFabric, EnterpriseLibrary.Caching, y otras que no vienen a caso ...), nuestro propósito es implementar nuestra propia lógica de Caché usando la clase Cache presente en el ensamblado System.Web.dll.

Adicionalmente crearemos una relación de dependencia entre el elemento almacenado en Caché y su correspondiente archivo en disco, pero de esto hablaremos mas adelante, de momento pasemos al código.

HttpRuntime.Cache & CacheDependency, Ejemplo de Código

Lo que haremos serán 2 métodos:

  1. Put: Escribir un objeto en Caché, y crear además una relación de dependencia con un archivo que también escribiremos en disco.
  2. Get: Leer un objeto de la Caché.

public static class MiAppCacheDependency

{

  public static bool Put(Object obj, string nameCache)

  {

    try

    {

      string filePathFullName = @"C:\Cache\" + nameCache + ".xml";

     

      File.WriteAllText(filePathFullName, obj.Serializa());

      // Crear la dependencia de la cache con el archivo 

      HttpRuntime.Cache.Insert(nameCache, obj, new CacheDependency(filePathFullName));

    }

    catch

    {

      throw new Exception("Error al escribir en cache, posiblemente no            

                           exista la carpeta CacheDependency.");

    }

    return true;

  }

 

  public static T Get<T>(string nameCache)

  {

    try

    {

      object cache = HttpRuntime.Cache[nameCache];

      if (cache == null) return default(T);

      return (T)cache;

    }

    catch { return default(T); }

  }

}

 

Veamos ahora como usar estos métodos. Imaginemos que tenemos una clase (Aerolíneas) para la gestión de las distintas aerolíneas. En esta clase tendremos:

  1.  CacheKey: Una propiedad de la clase que contendrá el nombre con que guardaremos las aerolíneas en la Caché.
  2. CacheGet: Un método que leerá las aerolíneas desde la caché, si estas no estuvieran, las leerá de la base de datos y la colocará en la caché.
  3. CachePut: Un método que escribirá las distintas aerolíneas en la caché.

namespace dllMiApp.Aerolineas

{

  /// <summary>

  /// Clase para la gestión de los Aerolineas

  /// </summary>

  public partial class Aerolineas

  {

    private static string CacheKey = "Aerolineas";

    /// <summary> 

    /// Escribe o inserta en cache las aerolíneas 

    /// </summary> 

    public static bool CachePut(List<Aerolinea> lstAerolineas)

    {

      return MiAppCacheDependency.Put(lstAerolineas, CacheKey);

    }

    /// <summary>

    /// Lee las aerolíneas desde cache. Sino existiera en chache, las lee de la BD

    /// </summary>

    public static List<Aerolinea> CacheGet()

    {

      List<Aerolinea> lstAerolineas = MiAppCacheDependency.Get<List<Aerolinea>>(CacheKey);

      if (lstAerolineas == null)

      {

        lstAerolineas = Aerolineas.GetAerolineasValidas();

        CachePut(lstAerolineas);

      }

     

      return lstAerolineas;

    }

  }

}

Nota: En los distintos métodos que actualicen las aerolíneas, deberíamos actualizar también su valor en la caché. Al existir una relación de dependencia entre la caché y un archivo en disco, garantizamos que al modificar la caché a través de una aplicación, todas las demás aplicaciones que usen la dependencia, se enterarán de la modificación.

 

Artículos Relacionados: