Category Archives: ajax

[ASP.NET Web API] Subiendo archivo con jQuery y Web API

Hola, hoy quiero mostrarles como podemos subir archivos al servidor utilizando jQuery y un servicio con ASP.NET Web API.

Lo primero es que vamos a definir el código HTML, lo importante es definir un input de tipo file:

<div class="jumbotron">
    <h1>ASP.NET Web API - File Upload</h1>
    <div class="row">
        <div class="col-md-12" style="font-size:medium">
            <div class="form-group">
                <label class="col-md-2 control-label">Archivo:</label>
                <div class="col-md-10">
                    <input id="inputFile" type="file" multiple="multiple" />
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Subir" id="btnUpload" class="btn btn-default" />
                </div>
            </div>
        </div>
     </div>
</div>

Ahora vamos a implementar la parte de JavaScript, en este caso vamos a asociar un manejador para el evento click del botón btnUpload y allí dentro haremos uso de AJAX para comunicarnos con el servidor:

$(document).on("ready", function () {
	$("#btnUpload").on('click', function () {
		var files = $("#inputFile").get(0).files;
		var data = new FormData();
		for (i = 0; i < files.length; i++) {
			data.append("file" + i, files[i]);
		}
		$.ajax({
			type: "POST",
			url: "/api/file",
			contentType: false,
			processData: false,
			data: data,
			success: function (result) {
				if (result)
				{
					alert('Archivos subidos correctamente');
					$("#inputFile").val('');
				}
			}
		});
	})
})

Lo que el código anterior hace es:

  1. Obtiene la colección de archivos seleccionados.
  2. Crea un nuevo objeto FormData y añade los archivos seleccionados
  3. Se realiza la petición al servidor utilizando AJAX (en este caso apoyados en jQuery), en url definimos la url del servicio (que vamos a crear en el siguiente paso), el verbo Http que es un POST y los datos a enviar.

Ahora el controlador:

public class FileController : ApiController
{
	public IHttpActionResult Post()
	{
		var request = HttpContext.Current.Request;
		if (request.Files.Count > 0)
		{
			foreach (string file in request.Files)
			{
				var postedFile = request.Files[file];
				var filePath = HttpContext.Current.Server.MapPath(string.Format("~/Uploads/{0}", postedFile.FileName));
				postedFile.SaveAs(filePath);
			}
			return Ok(true);
		}
		else
			return BadRequest();
	}
}

El código del controlador es sencillo, simplemente leemos la cantidad de archivos en el request y en caso de ser mayor a 0 iteramos sobre cada uno de ellos y lo guardamos.

Espero el ejemplo les sea de utilidad, saludos!

[ASP.NET Web API] Web API III – Consumiendo el servicio

Y seguimos con un nuevo post sobre Web API, ya en los dos pasados revisamos como crear un servicio con ASP.NET Web API y además como crearlo para trabajar un CRUD completo, pero hasta ahora no hemos consumido el servicio, lo cual es el objetivo de este post.

El ejemplo que usaremos será el creado en el post anterior así que dale una mirada: Creando un CRUD

Primero vamos a modificar un poco el HTML de la vista Index del controlador Home, para el ejemplo todas las operaciones las vamos a realizar allí:

<div class="hero-unit">
    <h2>Get All</h2>
    <div>
        <table id="tblList" class="table table-bordered table-hover">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Last Name</th>
                    <th>Twitter</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>
    </div>
    <h2>Get one</h2>
    <div>
        <ul>
            <li>
                <label>Id:</label>
                <input type="text" id="txtIdSearch" />
                <input type="button" id="btnSearch" value="Search" />
            </li>
            <li>
                <label>Name:</label>
                <input type="text" id="txtName" />
            </li>
            <li>
                <label>Last name:</label>
                <input type="text" id="txtLastName" />
            </li>
            <li>
                <label>Twitter:</label>
                <input type="text" id="txtTwitter" />
            </li>
            <li>
                <input type="button" id="btnDelete" value="Delete" />
                <input type="button" id="btnUpdate" value="Update" />
            </li>
        </ul>
    </div>
</div>
@section scripts
{
    <script type="text/javascript" src="@Url.Content("/Scripts/app/person.js")"></script>
}

Obtener todos

$(document).on("ready", function () {
    GetAll();
})

//Get all persons
function GetAll() {
    var item = "";
    $('#tblList tbody').html('');
    $.getJSON('/api/person', function (data) {
        $.each(data, function (key, value) {
            item += "
" + value.Name + "" + value.LastName + "" + value.Twitter + "
";
        });
        $('#tblList tbody').append(item);
    });
};

Lo primero que hacemos es validar que la página se ha cargado totalmente, luego realizamos un llamado a la función GetAll la cual se encarga de realizar la petición a la acción GetPerson() del controlador que retorna todo el conjunto de resultados, y cómo lo hace?, como estamos usando la función getJSON entonces ya la petición al verbo Get, y como no le estamos enviando parámetros entonces responde la acción que no recibe ninguno…si GetPeron(); luego con el $.each recorremos los elementos y llenamos la tabla.

Obtener un elemento

Ahora si queremos obtener 1 solo elemento, debemos pasarle el id que deseamos buscar, ya que el la acción en el controlador lo recibe GetPerson(Int32 id), entonces añadimos la siguiente función:

function GetPersonById(idPerson) {
    var url = '/api/person/' + idPerson;
    $.getJSON(url)
        .done(function (data) {
            $('#txtName').val(data.Name);
            $('#txtLastName').val(data.LastName);
            $('#txtTwitter').val(data.Twitter);
        })
        .fail(function (erro) {
            ClearForm();
        });
};

y al botón de buscar un manejador para el evento click:

$('#btnSearch').on('click', function () {
	GetPersonById($('#txtIdSearch').val());
})

De nuevo usamos $.getJSON, y en este caso cuando la petición se ejecuta correctamente entra al done donde asignamos valores a los campos de texto con los datos de la persona retornada, en caso que se produzca algún error se va la ejecución por el fail.

Eliminar un elemento por su id

Pasamos ahora a la eliminación, y en este caso vamos a enviarle el id de la persona que deseamos eliminar, por lo que se usará la acción DeletePerson(Int32 id), como antes lo primero es la función que hace el llamado:

function DeletePersonById(idPerson) {
    var url = '/api/person/' + idPerson;
    $.ajax({
        url: url,
        type: 'DELETE',
        contentType: &quot;application/json;chartset=utf-8&quot;,
        statusCode: {
            200: function () {
                GetAll();
                ClearForm();
                alert('Person with id: ' + idPerson + ' was deleted');
            },
            404: function () {
                alert('Person with id: ' + idPerson + ' was not found');
            }
        }
    });
}

luego el manejador para el botón y el evento click:

$('#btnDelete').on('click', function () {
	DeletePersonById($('#txtIdSearch').val());
})

En este caso hacemos uso de $.ajax, definimos la url y le adicionamos el id de la persona a eliminar, definimos el type (verbo Http a usar) en DELETE, y manejamos entonces el código Http como respuesta de consumir el servicio (statusCode), ya que si revisan la acción esta retorna un HttpResponseMessage, en donde se tiene un código 200 (HttpStatusCode.OK) cuando la eliminación es correcta o un 404 (HttpStatusCode.NotFound) cuando no se encuentra una persona con el id enviado o la eliminación falla.

Actualizar un elemento

Solo nos resta la actualización, así que primero la función:

function UpdatePerson(idPerson,person) {
    var url = '/api/person/' + idPerson;
    $.ajax({
        url: url,
        type: 'PUT',
        data: person,
        contentType: &quot;application/json;chartset=utf-8&quot;,
        statusCode: {
            200: function () {
                GetAll();
                ClearForm();
                alert('Person with id: ' + idPerson + ' was updated');
            },
            404: function () {
                ClearForm();
                alert('Person with id: ' + idPerson + ' was not found');
            },
            400: function () {
                ClearForm();
                alert('Error');
            }
        }
    });
}

luego el manejador para el botón y el evento click:

$('#btnUpdate').on('click', function () {
	var person = new Object();
	person.id = $('#txtIdSearch').val();
	person.name = $('#txtName').val();
	person.lastname = $('#txtLastName').val();
	person.twitter = $('#txtTwitter').val();
	UpdatePerson(person.id, JSON.stringify(person));
})

Al igual que para la eliminación usamos $.ajax pero en este caso el type lo definimos con el verbo PUT, en la url le pasamos el id de la persona y en el parámetro data le enviamos el objeto person y finalmente de nuevo validamos la respuesta usando los códigos Http, 200 (HttpStatusCode.OK), 404 (HttpStatusCode.NotFound) y 400 (HttpStatusCode.BadRequest).

En el llamado a la función creamos un nuevo objeto al cual le definimos los propiedades y sus correspondientes valores (mismos nombres que las propiedades en la clase C#) y la serializamos con JSON.stringify.

Insertar un nuevo elemento

Como última acción a implementar, ahora vamos a crear una nueva persona, primero entonces la función que hace el llamado:

function CreatePerson(person) {
    var url = '/api/person/';
    $.ajax({
        url: url,
        type: 'POST',
        data: person,
        contentType: &quot;application/json;chartset=utf-8&quot;,
        statusCode: {
            201: function () {
                GetAll();
                ClearForm();
                alert('Person with id: ' + idPerson + ' was updated');
            },
            400: function () {
                ClearForm();
                alert('Error');
            }
        }
    });
}

El manejador para el botón y el evento click:

$('#btnCreate').on('click', function () {
	var person = new Object();
	person.name = $('#txtName').val();
	person.lastname = $('#txtLastName').val();
	person.twitter = $('#txtTwitter').val();
	CreatePerson(JSON.stringify(person));
})

Y de nuevo aparece en escena $.ajax en esta ocasión con el type POST, y manejamos la respuesta de nuevo con códigos Http, el 201 (HttpStatusCode.Created) que indica que se creo el elemento y el 400 para el error.

Finalmente la sencilla aplicación se verá como:

crud

Y hasta llegamos por esta vez, espero les guste el post y les ayude a seguir con Web API, en el próximo post haremos un refactoring en el lado de cliente para usar Knockoutjs y su facilidad para implementar propiedades observables.

Saludos!

Descarga el ejemplo!

[ASP.NET MVC] Cargar una vista parcial con AJAX

Hola, una característica de ASP.NET MVC que me gusta bastante son las vistas parciales, y lo mejor de todo es que podemos usarlas en conjunto con AJAX de una manera realmente sencilla, ya que el mismo framework ofrece helpers que permiten realizar tareas comunes como la que vamos a ver en este post: cargar una vista parcial.

Vamos a realizar un pequeño formulario del tipo maestro – detalle, la idea es simular las ventas por mes, y en el detalle visualizar que producto se vendió por mes y su valor (tendremos datos estáticos, pero la idea es que se conectará con un repositorio de datos).

Primero vamos a definir dos clases como modelo (las clases son sencillas para realizar el ejemplo):

public class VentasMes
{
	public int Id { get; set; }
	public string Mes { get; set; }
	public int Valor { get; set; }
	public ICollection DetalleMes { get; set; }
}

public class DetalleMes
{
	public int Id { get; set; }
	public string Producto { get; set; }
	public int Valor { get; set; }
	public VentasMes VentasMes { get; set; }
}

Es necesario añadir una referencia al js jquery.unobtrusive-ajax, primero vamos a crear el bundle correspondiente (si usas la plantilla de Internet Application ya se tiene definida):

bundles.Add(new ScriptBundle(&quot;~/bundles/jqueryval&quot;).Include(
				&quot;~/Scripts/jquery.unobtrusive*&quot;,
				&quot;~/Scripts/jquery.validate*&quot;));

y luego la añadimos en el _Layout.cshtml:

@Scripts.Render(&quot;~/bundles/jqueryval&quot;)

Ahora, creamos el controllador VentasController con la acción List y algunos datos iniciales:

public class VentasController : Controller
{
	private readonly List ventasMes = new List()
	{
		new VentasMes()
		{
			Id = 1,
			Mes = &quot;Enero&quot;,
			Valor=200000,
			DetalleMes = new List(){
			   new DetalleMes(){ Id = 1, Producto = &quot;Producto 1&quot;, Valor = 50000},
			   new DetalleMes(){ Id = 1, Producto = &quot;Producto 2&quot;, Valor = 50000},
			   new DetalleMes(){ Id = 1, Producto = &quot;Producto 3&quot;, Valor = 50000},
			   new DetalleMes(){ Id = 1, Producto = &quot;Producto 4&quot;, Valor = 50000}
			}
		},
		new VentasMes()
		{
			Id = 2,
			Mes = &quot;Febrero&quot;,
			Valor=200000,
			DetalleMes = new List(){
			   new DetalleMes(){ Id = 1, Producto = &quot;Producto 1&quot;, Valor = 100000},
			   new DetalleMes(){ Id = 1, Producto = &quot;Producto 2&quot;, Valor = 100000}
			}
		},
	};

	public ActionResult List()
	{
		return View(ventasMes);
	}
}

Y ahora creamos la vista correspondiente List.cshtml:

@model IEnumerable&lt;PartialView_Ajax.Models.VentasMes&gt;

@{
    ViewBag.Title = &quot;Resumen&quot;;
}

&lt;h2&gt;Resumen Ventas&lt;/h2&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;th&gt;
            @Html.DisplayNameFor(model =&gt; model.Mes)
        &lt;/th&gt;
        &lt;th&gt;
            @Html.DisplayNameFor(model =&gt; model.Valor)
        &lt;/th&gt;
        &lt;th&gt;&lt;/th&gt;
    &lt;/tr&gt;

@foreach (var item in Model) {
    &lt;tr&gt;
        &lt;td&gt;
            @Html.DisplayFor(modelItem =&gt; item.Mes)
        &lt;/td&gt;
        &lt;td&gt;
            @Html.DisplayFor(modelItem =&gt; item.Valor)
        &lt;/td&gt;
        &lt;td&gt;
            @Ajax.ActionLink(&quot;Detalles&quot;, &quot;ViewDetails&quot;, new { id = item.Id }, new AjaxOptions { UpdateTargetId=&quot;divDetails&quot; })
        &lt;/td&gt;
    &lt;/tr&gt;
}

&lt;/table&gt;
&lt;div id=&quot;divDetails&quot;&gt;&lt;/div&gt;

Como se puede observar, se esta haciendo uso del helper de Ajax.ActionLink, este tiene varios constructores, sin embargo el que estamos utilizando requiere como primer parámetro el texto del link, el segundo es la acción del controlador que se ejecuta, el tercero los datos enviados a la acción y el cuarto permite definir varias opciones, en este caso solo utilizo UpdateTargetId el cual permite definir el id del control en donde mostrar el resultado de la acción, en este caso será la vista parcial, y entonces la acción:

public ActionResult ViewDetails(int id)
{
	var detalle = ventasMes
					.Where(c =&gt; c.Id == id)
					.Select(c =&gt; c.DetalleMes)
					.FirstOrDefault();
	return PartialView(&quot;_Details&quot;,detalle);
}

La diferencia a una acción normal es que se retorna PartialView en lugar de View, y allí estamos definiendo el nombre de la vista parcial (_Details) y como segundo parámetro el modelo, entonces la definición de la vista parcial:

@model IEnumerable&lt;PartialView_Ajax.Models.DetalleMes&gt;

&lt;fieldset&gt;
    &lt;legend&gt;Detalle x Mes&lt;/legend&gt;
    &lt;ul&gt;
        @foreach (var item in @Model)
        {
            &lt;li&gt;
                &lt;p&gt;@item.Producto (@item.Valor.ToString(&quot;c&quot;))&lt;/p&gt;
            &lt;/li&gt;
        }
    &lt;/ul&gt;
&lt;/fieldset&gt;

Y listo, finalmente lo que vamos a obtener es:

image

Espero les haya gustado el post, les dejo el código del ejemplo:

Descarga el ejemplo!

Saludos.

[ASP.NET] Update Panel y jQuery juntos es posible

Hola a todos, este es un post que quería hacer hace rato, y pues en los últimos días estuve varios comentarios de Cristian en un post anterior (filtrar gridview con jQuery), así que Cristian con este post te contesto, en resumen el problema radica en que cuando se tiene un updatepanel y se realiza alguna actualización las funcionalidades que se han implementado con jQuery se pierde, y esto ocurre simplemente porque al utilizar el updatepanel la página no se carga normalmente, y esto si es necesario para jQuery.

Para dar un ejemplo pensemos que tenemos una página en la cual tenemos un updatepanel, y allí dentro unos tabs, los cuales son creado gracias a jQuery UI, entonces la primera vez que se carga la página tenemos algo como:

Imagen1

Algo muy sencillo, lo interesante es que tenemos un botón, y cuando damos click en el botón lo que tenemos es que se realiza una actualización parcial de la página, lo cual hace que nuestros tabs dejen de funcionar Triste:

Imagen2

Y lamentablemente se han perdido los tabs… pero ahora vamos a la solución la cual realmente es muy sencilla, lo único que debemos utilizar en este caso es la Microsoft Ajax Library, y en el momento en que se termina la renderización parcial debemos volver a llamar el script que crea los tabs o los scripts que estemos utilizando:

   1:  <script type="text/javascript">
   2:          Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endReq);
   3:          function endReq(sender, args) {
   4:              $("#divTabs").tabs();
   5:          } 
   6:  </script>

Lo importante es que no olviden referenciar la librería Microsoft Ajax, en el ejemplo encontrarán el archivo correspondiente, y lo otro importante es que el código anterior debe ir dentro del body.

Espero les sea de mucha utilidad el ejemplo, les dejo el ejemplo para su descarga, hasta un próximo post!

Descargar el ejemplo!

jQuery – Cargando HTML externo

Hoy vamos a ver como utilizando AJAX podemos cargar HTML remoto en determinad página, de esta forma evitamos tener en nuestra página una gran cantidad de código HTML que hará mas pesada la misma.

Para cargar el HTML remoto vamos a utilizar como siempre jQuery y en este caso la función load, la sintaxis general es:

   1:  $("elemento").load('pagina.html');

Como se puede apreciar solo necesitamos un contenedor que generalmente será un div y la página que se quiere cargar.

Ahora vamos a ver que características tiene este evento load:

  • Carga todo el contenido comprendido dentro de la etiqueta body.
  • La página que se quiere cargar debe estar en el mismo dominio que la página desde la cual se hace el llamado.
  • Es posible especificar un elemento particular de la página a cargar, por ejemplo de la página about.html solo cargar el div con id igual a divInfo, la sintaxis seria:
   1:  $("elemento").load('about.html #divInfo');
  • Cuando se carga la página, solo se carga el HTML, por lo tanto si se tiene código JavaScript este no estará disponible, para solucionar este caso en la página  que realiza el llamado se debe definir el código necesario, para este caso no es posible hacerlo de la manera tradicional como se atacha un manejador de evento a un elemento, se debe hacer uso de la función live que permite asignar manejadores de eventos a elementos que se crean luego de la carga del DOM, les dejó un link donde hablé del tema: jQuery live.

Ahora vamos a implementar toda esa carreta con un ejemplo de verdad:

1. Tenemos una página aspx desde la cual vamos a realizar los llamados a las páginas externas, en definitiva nuestra página tenemos:

   1:  <div id="divAbout"></div>
   2:      <fieldset>
   3:          <legend>Cargar página completa</legend>
   4:          <ol id="olCompleta">
   5:              <li><a href="jQuery.htm">jQuery</a></li>
   6:              <li><a href="aspnet.htm">ASP.NET</a></li>
   7:          </ol>
   8:          <div id="divInfo"></div>
   9:      </fieldset>
  10:      <fieldset>
  11:          <legend>Cargar solo descripción</legend>
  12:          <ol id="olDescripcion">
  13:              <li><a href="jQuery.htm">jQuery</a></li>
  14:              <li><a href="aspnet.htm">ASP.NET</a></li>
  15:          </ol>
  16:          <div id="divOnlyDes"></div>
  17:      </fieldset>

y el código jQuery:

   1:   $(function () {
   2:              $("#divAbout").load('about.htm');
   3:              $("#olCompleta a").click(function (e) {
   4:                  var dirUrl = $(this).attr('href');
   5:                  $("#divInfo").load(dirUrl);
   6:                  e.preventDefault();
   7:              })
   8:              $("#olDescripcion a").click(function (e) {
   9:                  var dirUrl = $(this).attr('href') + ' #divDescripcion';
  10:                  $("#divOnlyDes").load(dirUrl);
  11:                  e.preventDefault();
  12:              })
  13:          })

Entonces la idea es:

  • En el div con id igual a divAbout se va cargar la página about.htm, la cual tiene la información de contacto.
  • En la primera lista olCompleta como su nombre lo indica se va a cargar la página objetivo de manera total cada vez que se de click en una de las opciones, en la variable dirUrl traemos la dirección de la página capturando el valor del atributo href, luego se realiza el cargue el el divInfo y finalmente con la línea e.preventDefault() lo que se hace es prevenir/cancelar el comportamiento normal del objeto, el cual sería enviarnos a una determinada página.
  • Casi igual que el punto anterior, la diferencia es que se especifica en la línea 9 que de la página a cargar solo queremos el elemento con id igual a divDescripcion.

2. En la estructura de nuestro sitio tenemos las páginas HTML que vamos a cargar, como se menciono anteriormente debes estar en el mismo dominio que la página que realiza el llamado, en la imagen se visualiza dicha estructura:

Imagen1

3. Finalmente la aplicación se verá así:

Imagen2

Como se observa en la imagen, se esta implementando un llamado a páginas html y el contenido se muestra en una sola página.

Bueno como pueden ver es bastante fácil cargar HTML remoto utilizando AJAX.

Les dejo EL ejemplo que implementa dicha funcionalidad:

Descarga del ejemplo !

FileUpload AjaxControlToolkit

En el artículo anterior (míralo acá) vimos como utilizar el FileUpload que ofrece ASP.NET,  y como poder realizar validación tanto en el cliente como en el servidor, sin embargo este control no funciona cuando tenemos un UpdatePanel, o no totalmente, en tal caso el FileUpload debería estar asociado a un trigger del UpdatePanel.

Para solucionar el problema anterior podemos utilizar el control AsyncFileUpload disponible en el AjaxControlToolkit. Veamos las ventajas y desventajas de este control:

Ventajas:

  1. Funciona en conjunto con el UpdatePanel.
  2. Funciona de manera asíncrona.
  3. Permite establecer un icono para indicar que se esta realizando el cargue.
  4. Control de eventos en el cliente y en el servidor

Desventajas:

  1. No funciona con Internet Explorer 9: En este punto tuve que activar la vista de compatibilidad.
  2. Una vez iniciada la subida del archivo no es posible cancelarla.
  3. Una vez utilizado el control, no es posible limpiar el contenido del mismo.
  4. No es posible saber el progreso de carga del archivo.
  5. La subida del archivo inicia una vez se seleccione el archivo.este se ha seleccionado.
  6. No es posible manejar múltiples archivos.

En relación a las ventajas y desventajas de este control, en mi opinión muy personal todavía es un control que no utilizaría en una aplicación de gran impacto, pero bueno vamos a ver como es que funciona:

Código HTML del control:

<cc1:AsyncFileUpload ID="AjaxUpload" runat="server" UploaderStyle="Modern" Width="350px"
     ThrobberID="imgLoading" OnClientUploadComplete="UploadComplete"
     OnClientUploadError="UploadError"  />
<asp:Image ID="imgLoading" runat="server" ImageUrl="~/ajax-loader.gif" />

Los atributos importante de este control son:

  1. UploaderStyle: Permite seleccionar dos estilos, Modern que muestra el control de selección con un estilo más bonito además de tener una imagen, y el estilo Traditional, el cual solo muestra el botón de selección con un texto que indica selección de archivo.
  2. ThrobberID: El id de la imagen que se mostrará cuando se este cargando el archivo.
  3. OnClientUploadComplete: Función JavaScript que se ejecuta una vez se ha realizado satisfactoriamente el cargue del archivo.
  4. OnClientUploadError: Función JavaScript que se ejecuta si se produce algún error al subir el archivo.

Funciones JavaScript:

function UploadComplete(sender, args) {
   var filename = args.get_fileName();
   var contentType = args.get_contentType();
   var text = "Nombre archivo: " + filename + ". Tamaño: " + args.get_length() + " bytes";
   document.getElementById('lblMensaje').innerText = text;
}
function UploadError(sender, args) {
   var text = "No se ha podio subir el archivo. " + args.get_errorMessage();
   document.getElementById('lblMensaje').innerText = text;
}

Con la función UploadComplete, mostramos el un label el nombre y el tamaño del archivo, mientras que con
la función UploadError informamos el error producido.

Funciones Servidor:

  1. UploadedComplete: Se ejecuta cuando el archivo se carga con éxito.
  2. UploadedFileError: Se lanza cuando el archivo esta corrupto.

Para realizar el guardado se dispone del método SaveAs el cual vimos en el artículo anterior.

En el próximo artículo vamos a revisar como implementar un FileUpload con jQuery.

Les dejo el código en VB como en C# del ejemplo:

Ejemplo en VB !

Ejemplo en C# !

GridView y PopupControlExtender

Hola a todos, a diario en mi trabajo, he tenido q trabajar bastante con el control gridview de asp, y he tenido que agregarle varias funcionalidades, para que sea mas amigable al usuario y para que su funcionamiento sea mas adecuado… asi que he decidido hacer varios post (este seré el primero sobre este control), para que cualquiera pueda mejorar la usabilidad de este control).

En este post, quiero mostrar como podemos mostrar detalles del gridview de forma “modal” con el popupcontrolextender, y asi darle mas usabilidad a nuestro gridview…
sin más carreta vamos a lo que nos interesa.

La idea es poder mostrar detalles de nuestro gridview con solo pasar el mouse por encima de un boton de detalles, como vemos en la siguiente imagen:

Asi, al pasar el mouse por cada uno de las imagenes, vamos a visualizar el nombre del pais y de la ciudad (un ejemplo simple, ya ustedes veran como aplicarlo).

Pero que necesitamos, como mencione anteriormente, vamos a usar el popucontrolextender del toolkit de ajax (si no lo tienes descargarlo aqui)

Ahora vamos a comenzar a constriur nuestro programa.

Agregamos un control grdiview a nuestra pagina aspx, y dentro de la definición de las columnas, agregamos un imagebutton y un popupcontrol extender, lo importante aqui, es que debemos comunicarnos con el servidor para poder hacer la consulta contra la base de datos y asi poder mostar los detalles, asi que en la propiedad DynamicServiceMethod del popupcontrolextender le damos el nombre de un WebMethodAttribute existente en nuesto codebehind, y en la propiedad DynamicContextKey le vamos a enviar los parametros para poder hacer los filtros en la consulta….

Dentro de nuestro WebMethodAttribute el cual debemos definir como shared en visual basic (static en c#), vamos a realizar laconsulta contra la base de datos, asi como se debe crear una tabla el la cual visualicemos los resultados…

Bien es sabido, que el popupcontrol se activa al dar click en un control (es nuestro caso imagebutton), y como la idea es mostrar los detalles con solo pasar el mouse por encima de la imagen, se debe agregar este comportamiento, lo cual hacemos en el evento rowcreated del gridview…alli agregamos los enventos onmouseover para mostrar los detalles al pasar el mouse por encima y onmouseout para ocultarlo cuando quitemos el mouse…

Como ven, no es algo complicado y si hará que nuestras aplicaciones sean más rápidas y mas fáciles para el usuario…lo cual es algo fundamental…

Link con el ejemplo !!

Espero les sea util este ejemplo y nos vemos en un próximo ejemplo, donde mostraré como hacer una paginación elegante y funcional del gridview…

Mensajes de usuario con Ajax

Muchas veces nos preguntamos, como mostrar mensajes al usuario en nuestra aplicación, ya sea informando sobre un error o bien indicando que una acción termino correctamente.

En esta ocasión, voy a mostrar como soluciones este problema usando el grandioso ajax, más en detalle el modalpopup extender.

La idea es mostrar tres tipos de mensajes (correcto,advertencia y error), para que el usuario sepa exactamente lo que ha sucedido. Así, la pariencia final de nuestros mensajes serán:

Lo primero que debemos hacer es añadir la referencia al toolkit de ajax, luego de agregarlo, definimos la interfaz (para el ejemplo serán tres botones, uno para cada tipo de diálogo).

Luego, añadimos un panel, esta panel será el encargado de contener el mensaje, y será el panel objeto del modalpopupextender de ajax.

Dentro del panel se han definido dos tablas, las cuales contendrán el encabezado del mensaje y el cuerpo del mensaje.

Luego añadimos el control de ajax, en donde pnlMensaje es el panel que contiene todo el cuadro de mensaje, el okcontrolid, es el id del control que cerrará el mensaje, BackgroundCssClass es el estilo definido para el resto de la pantalla, asi el usuario no podrá realizar ninguna acción mientras que el mensaje este visible, y el targetcontrolid “supuestamente” el control que mostrara el mensaje, pero luego veremos que no sera asi, sin embargo se debe definir el control con un estilo en display none para que no sea visto en la página.

Luego de crear la interfaz, pasamos al codebehind, y alli realmente sera en donde se llame cada mensaje.

Primero creamos una enumeracion, la cual contiene los tres tipos de mensajes:

Private Enum TipoMensaje
eerror = 1
correcto = 2
advertencia = 3
End Enum

Luego, creamos un procedimiento el cual se encargara de mostrar el mensaje, y definir el estilo q se aplicará. Este procedimiento recibirara dos parametros, el mensaje para el usuario y el tipo del mensaje (el cual sera sesgado por la enumeracion creadada). Dentro de la funcion definimos los estilos para cada mensaje dependiendo del tipo de mensaje recibido.

Private Sub mostrarmensaje(ByVal mensaje As String, ByVal Tipo As TipoMensaje)
Select Case CInt(Tipo)
Case 1
pnlMensaje.CssClass = “CajaDialogoError”
mensajeheaderPanel.CssClass = “MensajeHeaderError”
Case 2
pnlMensaje.CssClass = “CajaDialogoCorrecto”
mensajeheaderPanel.CssClass = “MensajeHeaderCorrecto”
Case 3
pnlMensaje.CssClass = “CajaDialogoAdvertencia”
mensajeheaderPanel.CssClass = “MensajeHeaderAdvertencia”
End Select
mensajeLabel.Text = mensaje
mpeMensaje.Show()
End Sub

y listo… ya tenemos para nuestro sitio tres tipos de mensajes… cualquier duda o comentario julito_gtu@hotmail.com

Puedes descargar el ejemplo aquí !!