ASP.NET

LINQ to SQL (I): Mapeo Objeto-Relacional


A estas alturas ya debemos de tener una idea bastante precisa del funcionamiento básico de LINQ. Hemos visto cómo lanzar consultas a listados de objetos (LINQ to Objects) e incluso algún ejemplo sobre cómo iterar sobre ficheros XML (LINQ to XML). Todas estas operaciones tienen un factor común: se realizaban sobre listados que implementaban la interfaz IEnumerable.

Además de poder lanzar consultas sobre listados de objetos, LINQ nos permite una opción aún más potente: lanzar consultas sobre bases de datos SQL Server mediante LINQ to SQL, que no es más que un mapper objeto-relacional, es decir, encargado de transformar sentencias LINQ en expresiones T-SQL y viceversa.

La potencia de LINQ to SQL radica en que, además de permitir realizar operaciones de consulta sobre una base de datos, también es posible realizar inserciones, actualizaciones y eliminaciones de forma nativa. A continuación veremos cómo realizar esto.

La principal desventaja de usar LINQ to SQL es que nuestra base de datos ha de ser, obligatoriamente, SQL Server (no obstante, existen proveedores LINQ para otras bases de datos, como LINQ to Oracle o LINQ to MySQL (vía NuGet). En caso de que todo esto falle y que necesitemos un proveedor personalizado, siempre podremos desarrollar por cuenta propia nuestro propio proveedor. En cualquier caso, siempre podremos utilizar un mapper objeto-relacional más genérico, como por ejemplo Entity Framework, del que hablaremos en posteriores artículos.

En este primer acercamiento a LINQ to SQL hablaremos de cómo establecer la relación entre nuestro programa (orientado a objetos) y nuestra base de datos (relacional). Para ello disponemos de varias posibilidades, que mostraremos a continuación:

(más…)

El Controlador en ASP.NET MVC 4 (III): Action Filters


Un Action Filter o filtro de acción es un atributo que puede asociarse a una acción de un controlador (o al controlador en su totalidad), modificando la forma en la que la acción se ejecuta. El Framework ASP.NET MVC proporciona unos cuantos, entre ellos:

Nombre Descripción
Authorize Restringe una acción para los roles o usuarios especificados.
HandleError Permite especificar una vista que se mostrará en caso de excepción no controlada.
OutputCache Almacena en caché la salida de un controlador
ValidateAntiForgeryToken Ayuda a evitar peticiones de falsificación de petición (pishing)
ValidateInput Desactiva las validaciones de petición. No es aconsejable hacer uso de este filtro salvo en ocasiones muy concretas, ya que pone en peligro la seguridad de la aplicación.

Además de los existentes, es posible crear filtros personalizados para fines definidos por el negocio (como por ejemplo, un sistema de autenticación personalizado).

Tal y como vimos brevemente en el artículo anterior con [HttpGet] y [HttpPost], las acciones pueden “condimentarse” con atributos que afectan a su funcionalidad. Los filtros se añaden a modo de atributo a las acciones, haciendo que su comportamiento varíe. Veamos un par de ejemplos.

(más…)

Instalar log4net en ASP.NET


Haremos una pequeña parada en el camino antes de proceder a explicar el funcionamiento de los Action Filters para aprender a configurar la herramienta de logging de Apache log4net. Esto se debe a que en el siguiente artículo crearemos un filtro personalizado que se encargará de trazar todas las operaciones realizadas por nuestros controladores, por lo que será requisito previo disponer de esta biblioteca instalada en nuestro proyecto.

Comenzaremos descargándonos log4net de la web de apache. Podemos obtenerlo desde aquí.

Hecho esto, abriremos el fichero .zip y nos dirigiremos al directorio que se corresponda con nuestra versión, en este caso, 4.0.


Localizaremos a continuación la biblioteca log4net.dll


(más…)

El Controlador en ASP.NET MVC 4 (II): Action Results


Hemos visto hasta ahora que nuestras acciones (recordemos que las acciones son los métodos públicos de un controlador) deben devolver un objeto de la clase ActionResult.

En ejemplos anteriores hemos utilizado los métodos View() y Content() para generar un objeto de este tipo, pero estos no son los únicos métodos que generan un resultado de una acción (ActionResult).

Dependiendo de la respuesta que queramos dar podremos hacer uso de los siguientes métodos, con sus correspondientes ActionResults, que generan desde texto plano (como Content()) hasta la lectura de un fichero (método File()) o la redirección a una nueva URL (método Redirect()):

MÉTODO ACTION RESULT DESCRIPCIÓN
Content() ContentResult Devuelve una cadena de texto.
EmptyResult (sin respuesta)
File() FileContentResult
FilePathResult
FileStreamResult
Devuelve el contenido de un fichero.
HttpUnauthorizedResult Devuelve un error de autorización (403)
JavaScript() JavaScriptResult Devuelve un fragmento de código JavaScript a ejecutar.
Json() JsonResult Devuelve datos en formato JSON.
Redirect() RedirectResult Redirecciona a una nueva URL.
RedirectToRoute()
RedirectToAction()
RedirectToRouteResult Redirecciona a otra acción.
View()
PartialView()
ViewResult
PartialViewResult
Traspasa el control a una vista.

A continuación echaremos un vistazo por encima a los elementos más importantes de esta tabla.

(más…)

Permitir conexiones locales a IIS y SQL Server en Windows 7


A la hora de desarrollar una aplicación .NET / ASP.NET con persistencia de datos, será necesario establecer una conexión con un servidor de base de datos. Generalmente, .NET suele hacer uso del binomio ASP.NET/SQL Server, para lo cual suelen darse, dejando a un lado los entornos de pruebas, integración y producción, dos escenarios típicos:

  • Utilizar una base de datos local en la que “cacharrear” y otra base de datos de desarrollo común a todos los desarrolladores de la aplicación.
  • Utilizar directamente una base de datos de desarrollo sin hacer uso de una base de datos local.

El segundo escenario típicamente suele consistir en un servidor SQL Server en red local, que bien puede ser dedicado (preferiblemente) o directamente (aunque sea mala práctica) el equipo de un compañero concreto.

Sin embargo, el acceso al equipo de un equipo en red local, políticas de red aparte, no es automático, sino que requiere permitir que tanto el servidor web (IIS 7 en nuestro caso) como el servidor de base de datos (ejemplificaremos con SQL Server 2012) permita el acceso a conexiones remotas y no sólo locales. Veremos a continuación cómo lograr este objetivo. (más…)

Añadiendo un TemplateField a un GridView de forma dinámica


La mayor parte de los sitios web que se sirven de listados lo hacen utilizando un esquema como el que sigue:

090501Grid
Como vemos, lo normal suele ser utilizar campos enlazados a la consulta (BoundFields), así como campos-plantilla (TemplateFields) con los que se suele interactuar con el listado (ver detalles, edición, etc.).

Si sabemos de antemano qué datos vamos a obtener, es sencillo “maquetar” nuestro GridView de forma sencilla. El problema radica en el momento en el que el número de columnas que nuestro GridView mostrará sea variable. En este caso, el atributo AutoGenerateColumns deberá ser puesto a True, con lo que perderemos el control del orden de los TemplateFields.

Veamos el siguiente caso: queremos un campo plantilla que muestre un LinkButton que nos permita editar el registro, y otro que nos permita visualizar los detalles del mismo. Queremos uno de estos campos en la primera columna (el de edición) y otro en la última (visualización). Si utilizamos TemplateFields con el atributo AutoGenerateColumns=”True”, lo que lograremos será que ambos botones se sitúen juntos en las dos primeras columnas de nuestro GridView. ¿Cómo hacer que uno de ellos se coloque al final? Añadiéndolo de forma dinámica.

Para comenzar, añadiremos un GridView con un TemplateField conteniendo un LinkButton, colocando el atributo AutogenerateColumns=”True”.

090502Grid
El templatefield contendría un LinkButton:

090503Grid

El resultado sería este:

090504Grid

Seguidamente, acudiremos a nuestro código, listos para editar el evento RowDataBound. En él haremos lo siguiente:

  • Declararemos una celda y un LinkButton.
  • Daremos formato al LinkButton (nombre, clase, etc.)
  • Asignaremos al LinkButton un CommandArgument igual al Identificador (DataKey) de esa fila del GridView
  • Añadiremos el LinkButton a la celda, y la celda a la fila

Para ello utilizaremos el siguiente código:


Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
Try

    ' Si se trata de una fila de datos...
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim celda As New TableCell()
        Dim boton As New LinkButton()

        boton.Text = "Detalles"
        If e.Row.Cells.Count > 1 Then
            boton.CommandArgument = GridView1.DataKeys(e.Row.RowIndex).Value.ToString()
        End If

        ' Añadimos el LinkButton a la celda, y la celda a la fila
        celda.Controls.Add(boton)
        e.Row.Controls.Add(celda)
    End If
Catch ex As Exception
    Throw ex
End Try
End Sub

Con esto lograremos el buscado esquema [Botón] [CAMPOS] [Botón].