Todas las entradas de: Javier Iglesias

Acerca de Javier Iglesias

Desarrollador de aplicaciones informáticas, diseñador Web y SEO

Copiar un proyecto de un repositorio remoto con Visual Studio 2013 y Git

Si necesitas empezar a trabajar en un proyecto de equipo que haya comenzado entonces necesitarás copiarte el proyecto en un repositorio local.

Para ello lo primero que debes hacer es añadir, si no lo tienes ya, un repositorio local donde vincularás los ficheros del proyecto. Para crear un repositorio debes ir a la ventana del Team Explorer dentro de Visual Studio 2013 y pulsar el botón con forma de enchufe «Conectar con proyectos de equipo» (vale simplemente con abrir el Visual Studio, no es necesario utilizar ningún proyecto creado).

Git Visual Studio Repositorio Remoto

Una vez creado el repositorio, debes seleccionarlo y después pulsar la opción de clonar:

Git Visual Studio Repositorio Remoto 2

En este punto Visual Studio te pemitirá introducir la url donde está ubicado el repositorio remoto (en este punto puedes meter un repositorio creado con BitBucket o GitHub). Además podrás seleccionar el repositorio local aunque aparecerá por defecto el repositorio seleccionado anteriormente que hemos creado en el punto anterior.

Cuando tengas todo preparado pulsarás el botón «Clonar» y obtendrás los ficheros del repositorio remoto a local.

Git Visual Studio Repositorio Remoto 3

Una vez haya terminado de recibir todos los ficheros entonces podremos ir a la ruta local de nuestro repositorio y abrir el proyecto que tendremos añadido directamente al control del código fuente. Ya podremos trabajar con él.

Recorrer un array con jQuery

Para recorrer un array con jQuery podemos utilizar el comando .each(). Su definición es:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

Es decir pasamos como primer parámetro el array y como segundo una función que recibe como el índice del elemento recorrido y su valor.

Un ejemplo de su uso:


var obj = { one: 1, two: 2, three: 3, four: 4, five: 5 };

jQuery.each( obj, function( i, val ) {
 $( "#" + i ).append( document.createTextNode( " - " + val ) );
});

En el ejemplo anterior se crearían los siguientes textos:

-1
-2
-3
-4
-5

…colocados respectivamente dentro de elementos dentro del DOM cuyos identificadores sean: «one», «two», «three», etc…

Consumir una API con jQuery y AJAX

En este post intentaremos aprender a consumir una API con jQuery y AJAX.

Nota: en el ejemplo que vamos a desarrollar partimos con que nuestro servicio API se encuentra en la misma web donde vamos a desarrollar el cliente.

Partimos también con que existen dos métodos en la API: obtención de una lista de todos los productos (URI: «/api/products») y seleccionar un producto por un identificador (URI: «/api/products/id«). La URI podrá cambiar dependiendo donde se ubique el servicio… en muchos casos puede ser del tipo «http://…»

Usaremos jQuery para realizar llamadas AJAX y actualizar la página con los resultados.

Empezamos por crear nuestro archivo vacío HTML. En él escribiremos lo siguiente:


<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <title>Product App</title>
</head>
<body>

<div>
 <h2>All Products</h2>
 <ul id="products" />
 </div>
 <div>
 <h2>Search by ID</h2>
 <input type="text" id="prodId" size="5" />
 <input type="button" value="Search" onclick="find();" />
 <p id="product" />
 </div>

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
 <script>
 var uri = 'api/products';

$(document).ready(function () {
 // Send an AJAX request
 $.getJSON(uri)
 .done(function (data) {
 // On success, 'data' contains a list of products.
 $.each(data, function (key, item) {
 // Add a list item for the product.
 $('<li>', { text: formatItem(item) }).appendTo($('#products'));
 });
 });
 });

function formatItem(item) {
 return item.Name + ': $' + item.Price;
 }

function find() {
 var id = $('#prodId').val();
 $.getJSON(uri + '/' + id)
 .done(function (data) {
 $('#product').text(formatItem(data));
 })
 .fail(function (jqXHR, textStatus, err) {
 $('#product').text('Error: ' + err);
 });
 }
 </script>
</body>
</html>

Nota: Existen muchas maneras de obtener jQuery, en este caso lo obtenemos de un recurso compartido en Internet (http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js)

Obtener la lista de productos

Para obtener la lista de productos se envía una petición HTTP (GET) a la uri donde se encuentra el servicio API. (/api/products).

La función de jQuery getJSON envía una petición asíncrona AJAX. La respuesta esperará por tanto un array de objetos JSON.  La función «done» especifica que la respuesta ha llegado. Cuando llegue la respuesta actualizaremos el DOM con la información que hemos recibido.


$(document).ready(function () {
 // Send an AJAX request
 $.getJSON(apiUrl)
 .done(function (data) {
 // On success, 'data' contains a list of products.
 $.each(data, function (key, item) {
 // Add a list item for the product.
 $('<li>', { text: formatItem(item) }).appendTo($('#products'));
 });
 });
});

Obtener un elemento pasando un identificador

Para obtener un producto por un un identificador, enviaremos un petición HTTP GET a «/api/products/id«, donde id es el identificador de producto.


function find() {
 var id = $('#prodId').val();
 $.getJSON(apiUrl + '/' + id)
 .done(function (data) {
 $('#product').text(formatItem(data));
 })
 .fail(function (jqXHR, textStatus, err) {
 $('#product').text('Error: ' + err);
 });
}

Programar una API con ASP.NET

Como sabemos el protocolo HTTP no sirve únicamente para servir páginas Web sino que también puede actuar como APIs que exponen servicios y datos. Estos servicios pueden ser consumidos por una gran cantidad de clientes como pueden ser navegadores, aplicaciones de escritorio, etc.

Crear un proyecto ASP.NET Web API

Centrándonos un poco más en ASP.NET, con Visual Studio 2013 existe la posibilidad de crear de una manera extremadamente fácil un proyecto API. Se hará a través de una plantilla.

Web API
Nuevo proyecto Web
Web API 2
Asignar plantilla Web API a la creación del proyecto

Gracias a esta plantilla Visual Studio nos creará automáticamente un esqueleto que nos permitirá poder añadir elementos de servicio que darán funcionalidad a nuestra API. En la anterior imagen creamos un proyecto vacío pero si nos fijamos también hemos marcado más abajo que queremos que nos añada los directorios y las referencias necesarias en el proyecto.

Como siempre las cosas se pueden hacer de distintas maneras… en este caso también se puede afrontar la creación de la API con MVC. En nuestro caso continuaremos sin utilizar MVC.

Añadir  un modelo

A continuación añadiremos un modelo. El modelo es un objeto que representa los datos de tu aplicación. ASP.NET Web API puede serializar automáticamente tu modelo a JSON, XML o cualquier otro formato y entonces escribir los datos serializados dentro del cuerpo de la respuesta HTTP. Además el cliente siempre puede indicar que formato quiere fijando la cabecera en la petición del servicio.

En este ejemplo añadiremos un modelo que represente un producto. Para ello haremos click derecho encima de la carpeta Models y añadiremos una clase.

Web API Modelo

Nombraremos la clase como «Product» y escribiremos el siguiente código:

namespace ProductsApp.Models
{
 public class Product
 {
 public int Id { get; set; }
 public string Name { get; set; }
 public string Category { get; set; }
 public decimal Price { get; set; }
 }
}

Añadir un controlador

En Web API, un controlador es un objeto que maneja peticiones HTTP. Añadiremos un controlador que devuelva una lista de productos o un único producto especificado por un Identificador.

Para añadir un controlador haremos click derecho sobre el directorio «Controllers» dentro de la solución y seleccionaremos «Controller».

Web API Controlador

En la nueva ventana elegiremos Web API Controller – Empty. Pulsaremos añadir.

Web API Controlador 2

Le podremos llamar «ProductsController» por ejemplo. Insertaremos el siguiente código dentro de este fichero:


using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;

namespace ProductsApp.Controllers
{
 public class ProductsController : ApiController
 {
 Product[] products = new Product[]
 {
 new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
 new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
 new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
 };

public IEnumerable<Product> GetAllProducts()
 {
 return products;
 }

public IHttpActionResult GetProduct(int id)
 {
 var product = products.FirstOrDefault((p) => p.Id == id);
 if (product == null)
 {
 return NotFound();
 }
 return Ok(product);
 }
 }
}

Si nos fijamos existen 2 métodos: GetAllProducts y GetProduct. Gracias a ASP.NET Web API podremos acceder a cada uno de estos métodos a través de las siguientes URIs: /api/products y /api/products/id.

Como vemos es muy sencillo programar una API con ASP.NET. En otro post hablaremos de cómo se puede consumir un servicio de este tipo con AJAX y jQuery.

Error en owin al renombrar proyectos

Si renombramos un proyecto o varios de ellos en una aplicación web y estamos utilizando Owin es posible que aparezca el siguiente error:

The following errors occurred while attempting to load the app.
– The OwinStartup attribute discovered in assembly ‘x’ referencing startup type ‘x.Startup’ conflicts with the attribute in assembly ‘y’ referencing startup type ‘y.Startup’ because they have the same FriendlyName ». Remove or rename one of the attributes, or reference the desired type directly.
To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of «false» in your web.config.
To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config.

Este error se suele producir porque existen dos ensamblados cargados en nuestra carpeta bin de la solución que contiene una clase startup. En la ejecución de la aplicación asp.net no sabe resolver cual de las dos clases debe ejecutar y de ahí el error.

La solución es ir a la carpeta bin y borrar la dll antigua que ya no es necesaria.

Esta página ya tiene más de 200 visitas mensuales y subiendo.
¡Gracias a todos los que lo hacéis posible!

Recargar página automáticamente mediante la intrucción Meta refresh

Igual no es una instrucción muy conocida (o al menos yo no la conocía hasta ahora) pero existe una opción en html para indicar al navegador que la página se refresque pasado un cierto número de segundos.

Esta instrucción se representa mediante la etiqueta meta y se debería insertar dentro de la etiqueta <head> aunque en algunos casos pueda funcionar fuera de ella:


...

<header>

<META http-equiv=refresh content=10>

...

En el ejemplo anterior le estamos diciendo que la página se refresque automáticamente cada 10 segundos.

Existe la opción de indicarle al navegador que pasados un cierto número de segundos debe redirigir a una url especificada. En el siguiente ejemplo haremos que el navegador vaya a la url: «pagina.com» pasados 5 segundos.


<meta http-equiv="refresh" content="5; url=http://pagina.com/">

En este otro ejemplo que aparece a continuación le indicamos que redirija a la url «pagina.com» inmediatamente asignando a content el valor 0.


<meta http-equiv="refresh" content="0; url=http://pagina.com/">

Esta es una manera bastante elegante de recargar página automáticamente únicamente con html. Lógicamente existen otras maneras como pueden ser scripts realizados en javascript, php, asp, etc…

Hacer un Response de cualquier tipo de contenido dentro de un UpdatePanel

Cuando trabajamos con UpdatePanel en ASP existe la posibilidad de que no se pueda realizar una respuesta de cualquier tipo de contenido sin realizar un postback.

Por ejemplo: creación de un fichero xls o xlsx de Excel.


...

HttpContext.Current.Response.ContentType = "application/ms-excel";

...

Si el control que hace de trigger se encuentra dentro del mismo updatepanel es muy posible que sea necesario indicar en el script que dicho control desencadenará el evento.


<asp:UpdatePanel runat="server" ID="upPanel">

<Triggers>

<asp:PostBackTrigger ControlID="btnTrigger" />

</Triggers>

...

</asp:UpdatePanel>