sábado, 20 de octubre de 2007

Un poquito de Ajax con ASP.NET

Ajax proporciona una nueva forma de hacer aplicaciones web más dinámicas, más útiles para el usuario, más atractivas, más rápidas y evitando el molesto refresco de pantalla. La forma en las que se pueden hacer con ASP.NET 2.0 es con la implementación Atlas ó con la librería libre de Ajax http://www.asp.net/ajax/.

Pues ahora quiero ver si me puedo explicar como hacer que el ComboBox sea llenado con datos desde una base de datos.

En el ejemplo de CascadingDropDown de los Control Toolkit se hace con una fuente de datos XML, y yo lo haré SQL Server 2005.

Requisitos

Empezamos con el hecho de que necesitamos ASP.NET 2.0 para poder usar estos controles con un Visual Studio 2005. En este caso utilizare el framework de Atlas aunque igualmente se podría haberse hecho con la librería de Ajax.

Debemos tener instalando el framework de Atlas que puedes encontrar en http://atlas.asp.net/

También hay que instalar el Atlas Control Toolkit y seguir estos pasos para configurar nuestros controles en Visual Studio:

Crear un nuevo website con “New”… “Website…” y seleccionar el ""Atlas" Web Site" que puedes encontrar en “My Templates”

En el Toolbox hacer click derecho y seleccionar “Add Tab” y escribir “Atlas Control Toolkit”
Adentro de este tab, dar click derecho y seleccionar “Choose Items…”

En la caja de diálogo dar click en Browse y navegar a la carpeta donde contengas el archivo "AtlasControlToolkit.dll". Encontrarás uno en donde hayas descomprimido el Atlas Control Toolkit, en SampleWebsite\bin.

Tener instalada la base de datos de prueba Northwind (disponible en Microsoft Downloads).

Ahora sí, podemos empezar con este ejercicio.

Procedimiento

Página web Atlas

Debemos crear un nuevo website (si no lo has hecho ya) y recuerda seleccionar “”Atlas” Website” de la lista de Templates disponibles.

Agregar a Default.aspx tres controles DropDownList simples y llamarlos apropiadamente, por ejemplo:

ddlEmployees
ddlOrders
ddlOrderDetails

El ScriptManager se puede dejar donde está, lo usa Atlas para su funcionamiento.

Agregar un CascadingDropDown Extender del tab de Atlas ControlToolkit:

El webservice

Sí, llenaremos los DropDown de una base de datos, pero nos resultará más sencillo si esos datos los obtenemos y proveemos con un Webservice, entonces en el Solution Explorer, en el nombre del proyecto damos click derecho y seleccionamos ”Add New Item…”, y en la caja de diálogo elegimos “Webservice” y lo nombramos:

Debemos incluir la librería de Atlas y para manejar datos:

using AtlasControlToolkit;
using System.Data;
sing System.Data.SqlClient;

El Webservice nos proveerá en realidad strings que el CascadingDropDown Extender puede manipular para llenar los DropDowns. Por lo que los Webmethods que creemos, los haremos a base de estos.

Nota importante: esta solución no es nada elegante, es sólo para efectos de muestra y el connectionString nunca hay que escribirlo así en soluciones de producción.

El primero, nos regresará simplemente los empleados:

[WebMethod] public CascadingDropDownNameValue[] GetEmployees( string knownCategoryValues, string category) {
SqlConnection connection = new SqlConnection(@"Data Source=SERVER\SQLEXPRESS; Initial Catalog=Northwind; Integrated Security=True");
SqlCommand command = new SqlCommand("SELECT * FROM Employees");
command.Connection = connection; connection.Open(); SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet dataSet = new DataSet();
adapter.Fill(dataSet);
command.Connection.Close();
ataTable tbl = dataSet.Tables[0];
List values = new List();
foreach (DataRow dr in tbl.Rows) {
string sEmployee = (string)dr["FirstName"] + " " + dr["LastName"];
int iEmployee = (int)dr["EmployeeID"];
values.Add(new CascadingDropDownNameValue( sEmployee, iEmployee.ToString()));
}
return values.ToArray();
}

Nótense los parámetros string knownCategoryValues, string category, éstos deben permanecer tal cual para que el control de CascadingDropDown haga con ellos su “magia”. La parte importante está después de List, que es la parte que construye los valores que finalmente llenan el DropDown de Employees. Se acomoda la presentación de lo que llevará el control y también el identificador del Employee que nos servirá para buscar las órdenes en el otro DropDown, de la siguiente manera:

[WebMethod] public CascadingDropDownNameValue[] GetOrdersByEmployee( string knownCategoryValues, string category) {
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
int iEmployee;
if (!kv.ContainsKey("Employee") !Int32.TryParse(kv["Employee"], out iEmployee)) {
return null;
}
SlConnection connection = new SqlConnection(@"Data Source=SERVER\SQLEXPRESS; Initial Catalog=Northwind; Integrated Security=True");
SqlCommand command = new SqlCommand("SELECT OrderID FROM Orders WHERE EmployeeID = " + iEmployee);
command.Connection = connection;
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter(command); DataSet dataSet = new DataSet(); adapter.Fill(dataSet);
command.Connection.Close();
DataTable tbl = dataSet.Tables[0]; List values = new List();
foreach (DataRow dr in tbl.Rows) {
string sOrder = dr["OrderID"].ToString();
int iOrder = (int)dr["OrderID"];
values.Add(new CascadingDropDownNameValue( sOrder, iOrder.ToString()));
}
return values.ToArray();
}

El WebMethod recibe como parámetro el EmployeeID dentro de knownCategoryValues y se hace una búsqueda del identificador con el cual filtramos la sentencia SQL para obtener las órdenes.

De igual forma, se prepara lo que alimentará el próximo DropDown en la última sección donde está el foreach. El WebMethod que prepara el detalle de las órdenes se filtra por el OrderID que se seleccione y se preparan los elementos para llenar el último dropdown.

Configuración de propiedades

El código para que los CascadingDropDown trabajen se captura en la definición del control viendo la fuente HTML presionando la vista de Source:

Y las propiedades se deben llenar de la siguiente forma: (en caso de no utilizar Atlas sino la libreria de Ajax no se tiene CascadingDropDownProperties, sino añadir 3 CascadingDropDown)

cc1:CascadingDropDown ID="CascadingDropDown1" runat="server">

cc1:CascadingDropDownProperties Category="Employee" ParentControlID="" PromptText="Select Employee" SelectedValue="" ServiceMethod="GetEmployees" ServicePath="Northwind.asmx" TargetControlID="ddlEmployees" />

cc1:CascadingDropDownProperties Category="Order" ParentControlID="ddlEmployees" PromptText="Select Order" SelectedValue="" ServiceMethod="GetOrdersByEmployee" ServicePath="Northwind.asmx" TargetControlID="ddlOrders" />

cc1:CascadingDropDownProperties Category="OrderDetail" ParentControlID="ddlOrders" PromptText="Select OrderDetail" SelectedValue="" ServiceMethod="GetDetailsByOrder" ServicePath="Northwind.asmx" TargetControlID="ddlOrderDetails" />

/cc1:CascadingDropDown>

Las propiedades a tomar en consideración son ParentControlID que son para indicarle el DropDown en el que se basará el contenido del control especicado en TargetControlID. Con la propiedad ServicePath indicaremos el WebService que tiene los webMethods para alimentar el control y éste WebMethod se especifica en la propiedad ServiceMethod.

Una cosa más a considerar es que en las propiedades de la página debemos especificar que no habilite validación de eventos para que funcionen correctamente los controles. En la misma vista de Source al inicio del código deberá incluirse:


%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableEventValidation="false" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableEventValidation="false" %>

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableEventValidation="false" %>

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableEventValidation="false" %>Después de esto, ya se puede ejecutar esta aplicación web y veremos que al entrar a esta página se alimentará el dropdown de Employee automáticamente. Y al seleccionar el Employee, se llenará y habilitará el siguiente control y pasará lo mismo con el que sigue.

No hay comentarios: