Archive for the Programación Category

Leyendo un fichero excel desde .NET con OLEDB

Posted in Programación with tags , , on 4 junio, 2009 by febrer

Este es un sencillo método para acceder a un fichero excel desde .NET utlizando OLEDB. Simplemente tenemos que indicar la ubicación del fichero en nuestro disco, y el nombre la la hoja a la cual queremos acceder. El paramentro HDR=NO, indica que la primera línea de la hoja excel no es el nombre de las columnas del datatable generado.

///
///
///
private DataTable GetExcel(string fileName, string sheetName)
{
OleDbConnection dbConn = null;
DataTable resultTable = new DataTable(sheetName);
// construimos la cadena de conexión.
string connString = “Provider=Microsoft.Jet.OLEDB.4.0;” +
“Data Source=” + fileName + “;Extended Properties=’Excel 8.0;HDR=NO;’”;

// creamos la conexión y la abrimos.
dbConn = new OleDbConnection(connString);
dbConn.Open();

if (!sheetName.EndsWith(“$”))
{
sheetName += ‘$’;
}
string query = string.Format(“SELECT * FROM [{0}]“, sheetName);
using (OleDbDataAdapter adapter = new OleDbDataAdapter(query, dbConn))
{
adapter.Fill(resultTable);
}

return resultTable;
}

Diferencias entre dos datatables

Posted in Programación with tags , , , on 10 febrero, 2009 by febrer

Este es un interesante script que devuelve la diferencia entre dos datatables. Su funcionamiento es similar a realizar un LEFT JOIN en Transact SQL. La diferencia es que en este método, utilizamos el objeto DataRelation de .NET. He tenido que utilizar este método ya que los origenes de los datatables, son de conexiones direferentes, por lo que la utilización de LEFT JOIN, no es posible.

///
/// Devuelve un datatable con las diferencias entre los datatables de entrada
///
///
1er datatable ///
2o datatable ///
public static DataTable Difference(DataTable First, DataTable Second)
{
//creamos una tabla vacia
DataTable table = new DataTable(“Diferencias”);

//creamos un dataSet para poder utilizar el objeto DataRelation
using (DataSet ds = new DataSet())
{
//añadimos una copia de las tablas
ds.Tables.AddRange(new DataTable[] { First.Copy(), Second.Copy() });
//creamos un dataColumn con las columnas del datatable 1.
DataColumn[] firstcolumns = new DataColumn[ds.Tables[0].Columns.Count];
for (int i = 0; i < firstcolumns.Length; i++)
{
firstcolumns[i] = ds.Tables[0].Columns[i];
}

DataColumn[] secondcolumns = new DataColumn[ds.Tables[1].Columns.Count];
for (int i = 0; i < secondcolumns.Length; i++)
{
secondcolumns[i] = ds.Tables[1].Columns[i];
}
//creamos la relación
DataRelation r = new DataRelation(string.Empty, firstcolumns, secondcolumns, false);
ds.Relations.Add(r);

//creamos las columnas en el datatable a devolver.
for (int i = 0; i < First.Columns.Count; i++)
{
table.Columns.Add(First.Columns[i].ColumnName, First.Columns[i].DataType);
}

//si la primera fila no esta en la segunda tabla, la añadimos a la tabla.
table.BeginLoadData();
foreach (DataRow parentrow in ds.Tables[0].Rows)
{
DataRow[] childrows = parentrow.GetChildRows(r);
if (childrows == null || childrows.Length == 0)
table.LoadDataRow(parentrow.ItemArray, true);
}
table.EndLoadData();
}

return table;
}

Urls amigables, “friendly urls”

Posted in Programación with tags , , , on 25 noviembre, 2008 by febrer

Ya no esta de moda el utilizar urls del tipo: http://www.miportal.com/pagina.aspx?id=345, ahora lo “cool” es: http://www.miportal.com/mi-titulo-de-pagina-amigable.aspx (lo ideal seria omitir .aspx).

Para realizar este tipo de redirección, utilizo el siguiente método (basado en proceso de la petición en el BeginRequest, de la página):

Dispongo de un portal (desarrollado por mi), llamado FSPortal, que básicamente, lo que hace es almacenar todas las páginas estáticas en base de datos. Esto me posibilita que mediante un editor online (FckEditor), pueda dar a mis clientes la posibilidad de editar sus páginas online. Entre otros muchos parámetros, se puede dar un título “amigable” a las páginas. Esto, a parte de otras muchas ventajas, me permite realizar búsquedas en el contenido.

Para realizar la redirección, lo que hago es utilizar este sencillo método: http://www.codeproject.com/KB/aspnet/urlrewriter.aspx

Creando una regla del tipo:

<rule>
<url>(.*).aspx</url>
<rewrite>procesar.aspx?tit=$1</rewrite>
</rule>

De esta manera, proceso todos los nombres de url amigables, con la pagina procesar.aspx, que básicamente lo que hace es buscar en la base de datos una página con dicho titulo, y mostrándola.

Uno de los mayores problemas que tiene este sistema, es que no permite la utilización de páginas sin extensión. En este post hablo de como utilizar la redirección con páginas sin extensión, pero no es muy recomendable.

También existen otras alternativas de terceros como por ejemplo:

http://www.urlrewriting.net

http://www.isapirewrite.com

La pega de estas opciones, es que debes tener control total del servidor IIS para instalar dichos componentes.

Páginas sin extensión en servidores compartidos

Posted in Programación with tags , , on 1 noviembre, 2008 by febrer

Un gran problema, que seguro a más de uno le ha pasado, es el no poder utilizar páginas sin extensión en su proyecto web. Normalmente los proveedores de Internet, supongo que para curarse en salud, no permiten el uso de este tipo de funcionalidades en sus servidores, ya que requiere de la instalación de software de terceros, o simplemente por tocar lo menos posible los servidores.

Generalmente, si necesitas este tipo de funcionalidades, lo que hacen es recomendarte contratar un producto superior, como servidores dedicados.

Un ejemplo sería, en vez de utilizar:

http://www.tuportal.com/pagina.aspx?id=240&sec=12

Utilizar:

http://tuportal.com/titulo-de-mi-pagina

La solución “temporal” que yo he encontrado, de momento (hasta encontrar una más elegante), es utilizar el evento Application_BeginRequest del global.asax y comprobar el QueryString del objeto Request.

Para ello, lo primero que tenemos que hacer es modificar el web.config para que utilize “customErrors”, de la siguiente forma:

<customErrors mode=”On” defaultRedirect=”nuestrapaginadeerror.aspx” />

De esta forma, cuando ocurra un error del tipo “Página no encontrada”, es nuestra aplicación la que gestiona dicho error.

Despues, lo que tenemos que hacer es modificar el evento Application_BeginRequest, para que determine si ha ocurrido un error 401.

        public void Application_BeginRequest(object Sender, EventArgs e)
        {
            string path = HttpContext.Current.Request.Path; // en path estará la página nuestrapaginadeerror.aspx
            string queryString = HttpContext.Current.Server.UrlDecode(HttpContext.Current.Request.QueryString.ToString());
            string webHttp = “http://&#8221; + HttpContext.Current.Request.ServerVariables["SERVER_NAME"];

            // cuando ocurre un error 401, en ‘querystring’ tenemos: “401;http://servidor.com/lapaginasolicitada&#8221;
            if (queryString.IndexOf(‘;’) != -1)
            {
                path = queryString.Split(‘;’)[1];
                path = path.Replace(webHttp, “”);

                HttpContext.Current.RewritePath(path);
            }
        }

Este mecanismo tiene una importante pega. La barra de direcciones es cambiada por el link original, es decir, se puede acceder con http://miportal.com/titulo, pero en la barra de direcciones, aparecerá http://miportal.com/pagina.aspx?id=34

 Quizá este matando moscas a cañonazos, pero si conoces alguna forma mejor, será bienvenida (no me vale poner un default.aspx en una carpeta :-)

Herramientas Ajax (Ajax Toolkit)

Posted in Programación with tags , on 16 octubre, 2008 by febrer

Llevo varios días buscando la manera de desarrollar un interface AJAX para mis desarrollos en ASP.NET. La respuesta directa sería ASP.NET AJAX …. pues no me convence. Es un gran producto, tiene una documentación genial, tutoriales, foros, etc, etc, pero hay dos cosas que no me gustan.

Primera, esta 100% pensado para desarrollos con los controles de ASP.NET. Es decir, si utilizas el grid de ASP.NET, genial, pero seguro que hay mas de uno que como yo, no utiliza los controles de ASP.NET, utiliza los suyos propios (generando el HTML manualmente).

La segunda pega es que el toolkit solo esta disponible para la versión 3.5 del framework. Este problema no es tan grave, ya que poco a poco, los proveedores de ISP, van actualizándose, pero el proveedor que yo utilizo, todavía no dispone de dicha versión.

Los productos que estoy barajando utilizar son:

Prototype
Dojo
Mochikit
Yahoo!
Google
JQuery

Dojo, es el producto que más me convence, ya que como Jquery, dispone de una programación basada en TAGS, que permiten añadir directamente nuevas funcionalidades a los controles HTML directamente. De esta manera la integración con mis desarrollos, debería ser muy rápida.

Este es un ejemplo de programación con Dojo (Grid):

    <table dojoType=”dojox.grid.DataGrid”
     region=”top” clientSort=”true” minSize=”20″ splitter=”true”
     jsId=”table”
     store=”mailStore” query=”{ type: ‘message’ }”
     onRowClick=”onMessageClick”
     style=”height: 150px; width: 100%;”>
     <thead>
      <tr>
       <th field=”sender” width=”10%”>Sender</th>
       <th field=”label” width=”80%”>Subject</th>
       <th field=”sent” width=”10%”>Date</th>
      </tr>
     </thead>
    </table>
    
    

Directamente al definir la tabla como “dojox.grid.DataGrid”, ya disponemos de un grid con ordenación de elementos, cambio de columnas, diseño, etc, etc.

Ejemplo de un desplegable (combo, con selección de elementos mientras escribes):

       <select dojoType=”dijit.form.ComboBox” id=”${id}_subject” hasDownArrow=”false” style=”width: 40em;”>
        <option></option>
        <option>progress meeting</option>
        <option>reports</option>
        <option>lunch</option>
        <option>vacation</option>
        <option>status meeting</option>
       </select>

 

Yahoo y Google, requieren un aprendizaje mucho mayor, y por lo que he visto no disponen de dicha funcionalidad. Evidentemente, utilizar productos de Google o Yahoo, ofrecen una mayor garantía, pero también valoro mucho la rápida integración. Lo que estoy buscando es no volverme loco con la programación en javascript.

Mi framework

Posted in Programación, Trabajos with tags , , on 9 octubre, 2008 by febrer

Bueno, al final me he decido a escribir algo. Tengo muy abandonado el blog, en este mes pasado solo he podido escribir un post. Desde que he empezado mi nueva etapa de trabajador por cuenta ajena, no tengo ni tiempo. Por supuesto tengo que seguir atendiendo a mis clientes, y eso también me lleva bastante tiempo. Mi mujer cualquier día me deja, y con razón.

En este post quería hablar del “mini” lenguaje que utilizo para la generación de portales. Este “mini” lenguaje, me permite crear páginas personales online, rápida y fácilmente.
Dispongo de unas 80 funciones que me permiten desde realizar operaciones matemáticas, acceso a base de datos, recuperación de variables globales, etc, etc.

Este es un fragmento del código que utilizo:

<!–
%frmInicio()%
%frmPaginacion(10)%
%frmTabla(productos,familia=%frmRequest(f)%)%
–>
<table>
 %frmRepetir()%
 <tr>
 <td>Nombre: </td> <td>%frmValor(nombre)%</td>
 <td>Categoría: </td> <td>%frmCombo(categoria)%</td>
 <td>Precio: </td> <td>%frmValor(precio)%</td>
 </tr>
 %finRepetir()%
</table>
%frmLinkAnterior()% / %frmLinkSiguiente()%

Con este código, lo que hago es crear una página con el contenido de la tabla “Productos”, con la condición de que los productos se selección en base a un parámetro pasado por GET. Se establece la paginación a 10 registros por página, y en el pie de página, se muestran los controles para paginar por las diferentes páginas.

Como todas las páginas de mis portales están almacenadas en base de datos, lo que hago es interpretar el contenido antes de mostrarlo en el navegador.

Como veréis, gracias a esta utilidad de mi framework, me permite la generación de aplicaciones rápidas y efectivas.

Se admiten sugerencias.

Ataques por inyección de código en URL

Posted in Programación with tags , , on 24 julio, 2008 by febrer

¿Quién no está sufriendo últimamente ataques de Inyección de SQL en URL?

Si te ha pasado como a mí, que tienes desarrollos antiguos en ASP contra SQL Server, y has sufrido alguna inyección del tipo: http://www.mitxatxidominio.com/mipaginitamalprogramada.asp?miparam=23;DECLARE%20@S%20VARCHAR(4000);SET%20@S=CAST(0x4445434C41524520405420564152434…txurro que te crio. Y si encima has tenido la mala suerte de no hacer un cast del request con cint y te la han colao ….., te habrás encontrado con código basura en todos los campos de texto de la base de datos.

Para limpiar la “mierda” de tu servidor, este es el procedimiento almacenado que he utilizado (es un procedimiento para realizar sustituciones de cadenas en todos los campos de texto de todas las tablas de tu BD) (USALO CON PRECAUCIÓN, Y RECETA MÉDICA):

CREATE PROC SearchAndReplace
(
@SearchStr nvarchar(100),
@ReplaceStr nvarchar(100)
)
AS
BEGIN

– Copyright 2002 Narayana Vyas Kondreddi. All rights reserved.
– Purpose: To search all columns of all tables for a given search string and replace it with another string
– Written by: Narayana Vyas Kondreddi
– Modificación: Juan Carlos Febrer
– Site: http://vyaskn.tripod.com
– Tested on: SQL Server 7.0 and SQL Server 2000 and SQL Server 2005
– Date modified: 2nd November 2002 13:50 GMT 

SET NOCOUNT ON

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110), @SQL nvarchar(4000), @RCTR int
SET @TableName = ”
SET @SearchStr2 = QUOTENAME(‘%’ + @SearchStr + ‘%’,””)
SET @RCTR = 0

WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ”
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + ‘.’ + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = ‘BASE TABLE’
AND QUOTENAME(TABLE_SCHEMA) + ‘.’ + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + ‘.’ + QUOTENAME(TABLE_NAME)
), ‘IsMSShipped’
) = 0
)

WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN (‘char’, ‘varchar’, ‘nchar’, ‘nvarchar’, ‘ntext’, ‘text’)
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)

IF @ColumnName IS NOT NULL
BEGIN
SET @SQL= ‘UPDATE ‘ + @TableName +
‘ SET ‘ + @ColumnName
+ ‘ = REPLACE(cast(‘ + @ColumnName + ‘ as varchar(8000)), ‘
+ QUOTENAME(@SearchStr, ””) + ‘, ‘ + QUOTENAME(@ReplaceStr, ””) +
‘) WHERE ‘ + @ColumnName + ‘ LIKE ‘ + @SearchStr2
EXEC (@SQL)
SET @RCTR = @RCTR + @@ROWCOUNT
END
END
END

SELECT ‘Replaced ‘ + CAST(@RCTR AS varchar) + ‘ occurence(s)’ AS ‘Outcome’
END

 

Esta es una versión modificada de la realizada por Narayana Vyas Kondreddi que permite buscar y sustituir también en los campos “ntext” y “text” (memo).

Si deseas más información sobre este tipo de ataques, te recomiendo:

-Técnicas avanzadas en ataques Blind SQL Inyección (Chema Alonso)
-Protegerse de las inyecciones SQL por URL (Rodrigo Corral)
-Gustavo Velez (SkunkWorks)

Lumidigm Venus

Posted in Programación with tags , , on 7 julio, 2008 by febrer

Lumidigm, dispone de un producto muy interesante llamado “Venus”. Es un escáner de huellas digitales. Dispone de un SDK que permite su fácil utilización en diferentes entornos. Yo lo he utilizado en .NET con c# y me ha parecido muy fácil de usar. Para facilitarme las cosas, he creado un UserControl con las funciones básicas y un proyecto demo.

A continuación os facilito un sencillo ejemplo para facilitaros el desarrollo.

Ejemplo c#

Debes instalar el SDK v2.31 que viene con el producto. Si lo instalas en una dirección diferente de C:\Archivos de programa\Lumidigm\SDKv2.31 , deberás cambiar el path en el SDK Helper.

Nota: La versión de SDK Helper que os facilito es una versión propia, que corrige un problema con el Score y Spoof. Es un problema muy sencillo que supongo en versiones superiores la corrijan.

Pruebas unitarias

Posted in Programación with tags , on 15 mayo, 2008 by febrer

Hoy he descubierto una funcionalidad muy interesante de Visual Studio 2008. La generación automática de las clases necesarias para realizar las pruebas unitarias. Básicamente, lo que realiza esta opción es generar el esqueleto necesario para realizar los test unitarios.

Antes de nada, los test unitarios son unas pruebas predefinidas por nosotros para el correcto uso de nuestra aplicación. Por ejemplo:

        /// <summary>
        ///A test for GetFileName
        ///</summary>
        [TestMethod()]
        public void GetFileNameTest()
        {
            Functions target = new Functions();
            string path = "c:\\mydir\myfile.txt";
            string expected = "myfile.txt";
            string actual;
            actual = target.GetFileName(path);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

Esta función me permitirá evaluar el correcto funcionamiento del método GetFileName, el cual devuelve el nombre del fichero, pasándole un path.

A lo que íbamos, desde VS2008, se puede generar el esqueleto para realizar las pruebas unitarias. Con botón derecho en cualquier parte de nuestro fuente, seleccionamos “Create unit test …”. Esta opción será visible siempre que en nuestra solución tengamos un proyecto de tipo “Test”. Marcamos las clases que deseamos generar y sorpresa… nuestro esqueleto de pruebas generado.

Ahora queda lo más difícil, ir modificando cada función, método, etc, para que realice la prueba correcta.

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.