[Azure] Azure Web Sites – Escalamiento

Posted on Actualizado enn

Hola, en el post anterior hablamos de cómo podemos integrar un Azure Web Site con un repositorio, para así automatizar el proceso de despliegues y tener la posibilidad de realizar rollbacks en cualquier momento; hoy vamos a ver como es posible escalar dicho Web Site, bastante útil cuando ya lo que viene por default no es suficiente.

Para comenzar a escalar el Web Site, seleccionamos la opción SCALE, por defecto nuestro Web Site corre en el modo FREE con 1 sola instancia:

escalamiento1

Bien, para este ejemplo vamos a escalar a STANDARD, y automáticamente tenemos nuevas opciones disponibles como:

  • Escoger Web Site: Permite seleccionar el Web Site.
  • Tamaño de instancia: Permite escoger entre Small, Medium y Large, lo cual se verá reflejado en el tamaño de la máquina virtual.
  • Número de instancias: Permite seleccionar el número de instancias asociadas al Web Site.
  • Escalamiento: Permite escalar el Web Site en una hora determinada, o por algún consumo de CPU específico.

escalamiento2

Ahora hagamos enfásis en la parte de escalamiento, si escogemos en la metrica que escale por CPU, dos opciones nuevas se habilitan, la cantidad de instancias y el consumo de CPU (rango de uso de CPU), allí entonces definimos el número de instancias (mínimo y máximo) cuando el consumo de CPU este en un rango determinado:

escalamiento3

La otra opción es configurar el escalamiento para una hora determinada, esto es bastante útil cuando conoces con anterioridad los picos de tráfico del Web Site, para ello damos click en Set up schedule times, y en el modal que se muestra configuramos el escalamiento, allí inicialmente podemos escoger entre escalamiento diferente para el día y la noche y/o para días entre semana y fines de semana, y luego establemos los horarios:

escalamiento4

Al confirmar ya tenemos disponible los escalamientos creados, solo resta decirle que número de instancias vamos a usar:

escalamiento5

Espero el post les sea interesante, hasta la próxima!

Saludos!

[Azure] Azure Web Sites – Integración con repositorios

Posted on Actualizado enn

Hola, ultimamente he visto varias personas que ven los Azure Web Sites como simples “hosting”, creyendo que para lo único que sirven es para publicar tu sitio Web y… listo, así que pienso hacer una pequeña serie de post para mostrar algunas características que permiten a los Azure Web Sites ser un componente robusto e interesante.

En este post vamos a revisar como es posible enlazar el Azure Web Site con algún tipo de respositorio (Visual Studio Online, Git Local, GitHub, Dropbox, Bitbucket, CodePlex o alguno externo) para automatizar los despliegues, en ese caso vamos a relacionarlo con un repositorio en GitHub, para ello vamos al dashboard del Web Site y seleccionamos Set up deployment from source control, luego se abre una ventana modal para elegir el tipo de repositorio, por lo que para este ejemplo escogemos GitHub:

repositorio

Luego nos pide autenticarnos con nuestra en GitHub, una vez confirmada la autenticación, escogemos el repositorio y el branch:

branch

Una vez finalizada la integración, Windows Azure se encarga de realizar el despliegue y nos informa del mismo:

info deploy

Uno de los puntos interesantes de esta integración, es que cada vez que se haga commit al repositorio el GitHub, Azure realizará el despliegue de los cambios y vamos a ver el historial de todos ellos:

historial despliegues

Si por alguna razón, necesitamos volver a un deploy anterior, lo podemos hacer sin problema, basta con seleccionar el deploy y en la parte inferior seleccionar Redeploy para hacer el rollback a una versión anterior:

redeploy

Espero les sea de utilidad, en próximos post seguiremos hablando de los Azure Web Sites!

Saludos!

[C#] Custom value resolver en AutoMapper

Posted on Actualizado enn

Hola, anteriormente hicimos una introducción a AutoMapper, vimos algunos conceptos básicos para rápidamente ponernos a tono con dicha herramienta y finalmente comente algunas características importantes y muy comúnmente utilizadas, y como podrán adivinar quedaron algunos temas por fuera, así que en esta oportunidad vamos a revisar una de ellas, los Value Resolver.

En esencia podemos crear un Value Resolver personalizado para especificar un mapeo diferente al por defecto (propiedad origen a propiedad destino) para cumplir con necesidades específicas, así que en esta oportunidad vamos a personalizar la asignación a la propiedad Name de la clase ClientViewModel. Así que vamos a cambiar un poco la clase ClientViewModel, donde eliminamos la propiedad LastName, así nuestra clase ahora solo tiene dos propiedades, Name y Email:

public class ClientViewModel
{
	public string Name { get; set; }

	public string Email { get; set; }
}

La concatenar las propiedades Name y LastName de la clase Cliente y ese valor será el asignado para el Name de ClientViewModel, así que vamos a crear un Value Resolver que nos ayude con esa tarea, crear un Value Resolver personalizado es tan simple como tener una clase que herede de ValueResolver y sobre-escribir el método ResolveCore. Así que creamos una clase llamada FullNameResolver que hereda de ValueResolver y definimos el source (la clase cliente original) y el tipo de la salida (un string en este caso), y en el override del método ResolveCore simplemente concatenamos las propiedades y retornamos el valor:

public class FullNameResolver : ValueResolver<Client, string>
{
	protected override string ResolveCore(Client source)
	{
		return string.Format("{0} {1}",source.Name, source.LastName);
	}
}

Ya que se ha creado el resolver, solo resta usarlo, así que vamos a nuestra clase CustomDto y allí en el método Configure en la definición del mapeo de la propiedad Name llamamos el resolver creado con la función ResolveUsing y le pasamos el FullNameResolver creado anteriormente:

protected override void Configure()
{
	Mapper.CreateMap<Client, ClientViewModel>()
		.ForMember(d => d.Name, o => o.ResolveUsing<FullNameResolver>())
		.ForMember(d => d.Email, o => o.MapFrom(c => c.Email));
}

Por último una prueba:

ValueResolver

Hasta la próxima, saludos!

[C#] AutoMapper desde ceros

Posted on Actualizado enn

Hola a todos, hoy vamos a ver una pequeña guía sobre AutoMapper, iniciando desde cómo instalarlo  y mirando algunas de sus características.

AutoMapper básicamente es una herramienta que permite realizar un mapeo de un objeto a otro ahorrandonos gran cantidad de código y que provee algunas utilidades para personalizar cómo se realiza dicho mapeo entre objetos.

Realizar mapeo entre objetos en una funcionalidad común en muchos de nuestros desarrollos, ya que permiten personalizar la salida de los datos evitando revelar información confidencial y dando al cliente solo la información que él realmente necesita, basandonos en dicha afirmación, pensemos en una clase (modelo) Cliente que tiene campos como Id, nombre, apellido, edad, email, fecha de creación y clave entre otros, y ahora tenemos alguna funcionalidad que expone la información del cliente, en este caso estamos revelando información que no deberiamos entregar como la fecha de creación y la clave, en ese caso lo que podemos hacer es crear una nueva clase (conocída como ViewModel) con solo los campos que vamos a exponer; y aquí es donde AutoMapper juega un papel importante ya que nos va a ayudar a pasar de nuestro modelo/clase Cliente a nuestro ViewModel ClienteViewModel de una forma bastante sencilla y robusta.

Para ver como funciona AutoMapper vamos a partir de una aplicación Web con ASP.NET MVC, sin embargo es posible usarlo en cualquier otro tipo de aplicación.

Lo primero es la instalación, y como podrán adivinar tan solo debemos añadir AutoMapper haciendo uso de Nuget:

AutoMapper

Ahora vamos a crear el modelo, en este caso la clase Client:

public class Client
{
	public int ClientId { get; set; }

	public string Name { get; set; }

	public string LastName { get; set; }

	public string Email { get; set; }

	public string CreationDate { get; set; }

	public string Password { get; set; }
}

Como ya mencionamos, necesitamos un ViewModel, que no es más que otra clase con el nombre ClientViewModel:

public class ClientViewModel
{
	public string Name { get; set; }

	public string LastName { get; set; }

	public string Email { get; set; }
}

Ahora, vamos a crear una sencilla clase que va a actuar como repositorio y va a retornar un cliente (realmente un ClientViewModel) dado su id:

public class ClientRepository
{
	private readonly List<Client> clients = new List<Client>() 
	{ 
		new Client(){ 
			ClientId = 1, 
			Name = "Julio", 
			LastName = "Avellaneda", 
			Email="julito_gtu@hotmail.com", 
			CreationDate = DateTime.Now, 
			Password = "123456"}
	};

	public ClientViewModel GetById(int id)
	{
		//Get the client
		var client = clients[0];
		//Define the mapping
		AutoMapper.Mapper.CreateMap<Client, ClientViewModel>();
		//Execute the mapping
		var clientViewModel = AutoMapper.Mapper.Map<Client, ClientViewModel>(client);
		//Return a viewmodel
		return clientViewModel;
	}
}

En el método anterior hacemos uso del método CreateMap de AutoMapper.Mapper para definir el mapeo de objetos, el primer parámetro es el objeto original (para el ejemplo Client) y el segundo parámetro es el objeto al cual se va a mapear (en este caso ClientViewModel), luego para que la magia funcione usamos el método Map para que se conviertan los objetos.

En el ejemplo anterior, AutoMapper realiza el mapeo entre las propiedades que tengan el mismo nombre y tipo de dato entre el modelo original y el ViewModel, razón por la cual poco hemos realizado en el método, sin embargo dicha premisa no se cumple siempre, ya que no en todos los casos las propiedades tienen el mismo nombre y puede existir alguna lógica adicional que se requiera implementar.

La siguiente imagen lo muestra claramente:

mappervm

Para casos más complejos que no cumplen la premisa básica del caso anterior, AutoMapper tiene una característica conocida como perfiles, y allí podemos definir un comportamiento más personalizado para los mapeos, para definir un perfil tenemos tres sencillos pasos:

  1. Crear una clase que herede de Profile (AutoMapper.Profile)
  2. Sobreescribir la propiedad ProfileName (Nombre del perfil)
  3. Sobreescribir el método Configure (Lógica del mapeo)

Entonces vamos a crear la clase CustomDto y realizamos los tres pasos anteriores, como nombre del perfil (propiedad ProfileName) definimos CustomDto, y por el momento vamos a dejar sin lógica el método Configure:

public class CustomDto : Profile
{
	public override string ProfileName
	{
		get
		{
			return "CustomDto";
		}
	}

	protected override void Configure()
	{
		
	}
}

Ahora vamos a centrarnos en el método Configure, de nuevo hacemos uso de AutoMapper.Mapper.CreateMap con objeto origen y objeto destino, y ahora para la personalización de como será llevado a cabo el mapeo entre los objetos, para ello hacemos uso del método ForMember, entonces para el ejemplo que veníamos trabajando el método Configure sería (por el momento no vamos a personalizar nada):

protected override void Configure()
{
	Mapper.CreateMap<Client, ClientViewModel>()
		.ForMember(d => d.Name, o => o.MapFrom(c => c.Name))
		.ForMember(d => d.LastName, o => o.MapFrom(c => c.LastName))
		.ForMember(d => d.Email, o => o.MapFrom(c => c.Email));
}

Ya que tenemos el perfil listo, ahora debemos llamarlo, y un buen lugar para hacerlo es en el evento Application_Start del Global.asax:

protected void Application_Start()
{
	AreaRegistration.RegisterAllAreas();
	FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
	RouteConfig.RegisterRoutes(RouteTable.Routes);
	BundleConfig.RegisterBundles(BundleTable.Bundles);

	AutoMapper.Mapper.Initialize(c => c.AddProfile(new CustomDto()));  
}

Ahora vamos a crear un nuevo método en la clase repositorio con el nombre GetByIdWithProfile para ver que para usar el perfil simplemente eliminamos la definición del mapeo:

public ClientViewModel GetByIdWithProfile(int id)
{
	//Get the client
	var client = clients[0];
	//Execute the mapping
	var clientViewModel = AutoMapper.Mapper.Map<Client, ClientViewModel>(client);
	//Return a viewmodel
	return clientViewModel;
}

Y si volvemos a probar efectivamente funciona sin problemas:

mappervm2

Hasta el momento se ha usado la funcionalidad por defecto de AutoMapper, así que vamos con el primer caso, en donde vamos a controlar cuando el valor de la propiedad origen es null, primero que pasa si por ejemplo la propiedad LastName no tiene un valor:

mappervmnull

Como podemos ver, la propiedad del ViewModel también tendrá el valor, así que por alguna regla de negocio, cuando el cliente no tiene un valor en LastName se debe mostrar el texto “-“, dicha regla de negocio la podriamos implementar en nuestra capa de UI o validando el valor de la propiedad antes de retornar el objeto… o aún mejor, en la definición del mapeo de AutoMapper, así que volvemos al método Configure y hacemos uso de NullSubstitute:

protected override void Configure()
{
	Mapper.CreateMap<Client, ClientViewModel>()
		.ForMember(d => d.Name, o => o.MapFrom(c => c.Name))
		.ForMember(d => d.LastName, o => o.NullSubstitute("-"))
		.ForMember(d => d.Email, o => o.MapFrom(c => c.Email));
}

Y probando de nuevo:

mappervmnullsub

Otro caso típico, se da cuando necesitamos trabajar con colecciones de datos en lugar de 1 solo objeto, en este caso prácticamente es transparente el cambio, basta solo con especificar en el método Map que por ejemplo usaremos un IEnumerable, para mostrarlo de nuevo creamos un nuevo método en nuestra clase repositorio:

public IEnumerable<ClientViewModel> GetAll()
{
	//Execute the mapping
	var clientViewModel = AutoMapper.Mapper
						.Map<IEnumerable<Client>, IEnumerable<ClientViewModel>>(clients);
	//Return a viewmodel
	return clientViewModel;
}

Y de nuevo probando:

mappervmlist

Y por el momento vamos a dejar aquí, la idea del post era dar una rápida introducción a AutoMapper y creo que ha sido así, en próximos post veremos otras características de esta poderosa herramienta.

Saludos.

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

Posted on Actualizado enn

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!

[Review] Review del libro Learning JavaScriptMVC

Posted on Actualizado enn

JavaScriptHace una par de días, estuve leyendo el libro Learning JavaScriptMVC, y me gustaría compartir con ustedes un pequeño review para ver si se animan a leerlo.

El libro consta de 124 páginas, lo cual facilita el ser leído rápidamente, esta enfocado a tratar el framework JavaScriptMVC y a darte las bases para que rápidamente puedas utilizar dicho framework si es que ya no lo estás haciendo, el libro tiene seis capítulos que son:

Capítulo 1: Getting Started with JavaScriptMVC

Una rápida introducción al framework JavaScriptMVC, revisando sus principales características y las ventajas que ofrece su uso, así mismo se enumeran y explican sus principales componentes, para abordarlos más específicamente en los siguientes capítulos.

Capítulo 2: DocumentJS

Capítulo dedicado al componente DocumentJS, en el cual podemos ver como documentar nuestro JavaScript de una buena forma, y ofrece una buena explicación sobre las directivas que podemos utilizar.

Capítulo 3: FuncUnit

Una parte fundamental de toda aplicación es que pueda ser testeada, por eso tenemos un capítulo dedicado a realizar pruebas funcionales utilizando FuncUnit.

Capítulo 4: jQueryMX

jQueryMX es una colección de librerías jQuery que ofrecen caracteríasticas para trabajar con AJAX, con formato JSON, manejo del DOM entre otros, y es un componente clave en JavaScriptMVC, así que otro capítulo dedicado a revisar dicho componente.

Capítulo 5: StealJS

StealJS es uno de los componentes más interesantes en JavaScriptMVC, este provee un set de funcionalidades bastante amplio los cuales los agrupan en Dependency management, Concatenation and compression, Logger, Code generator, Package management and Code cleaner, así que tenemos un capítulo dedicado a dichas características las cuales son bastante amplias.

Capítulo 6: Building the App

Y el capítulo final, luego de algo de teoría para entender JavaScriptMVC, viene la parte más interesante, la construcción de una aplicación utilizando los conceptos anteriores.

Es un libro bastante sencillo de leer, el cual aborda de forma sencilla los conceptos básicos de JavaScriptMVC y nos lleva por cada componente para entender su uso, así que si quieres aprender un buen framework para el front-end este puede ser una buena elección.

Y de nuevo gracias a los amigos de Packt por el libro!

Saludos.

[ASP.NET MVC] Implementando el helper chart de Kendo UI

Posted on

Hola a todos, hoy quiero mostrarles como es de sencillo crear un chart utilizando los helpers de Kendo UI para ASP.NET MVC, lo primero es referenciar la dll Kendo.Mvc:

referencia kendo

Luego los archivos JavaScript y CSS:

css.js.kendo

Creamos los bundles correspondientes en la clase BundleConfig:

bundles.Add(new ScriptBundle("~/bundles/kendo").Include(
	"~/Scripts/kendo/kendo.all.min.js",
	"~/Scripts/kendo/kendo.aspnetmvc.min.js"));
	
bundles.Add(new StyleBundle("~/Content/kendocss").Include(
	"~/Content/kendo.common.min.css",
	"~/Content/kendo.flat.min.css",
	"~/Content/kendo.dataviz.flat.min.css"));

Y los referenciamos en la sección head del layout:

@Styles.Render("~/Content/css")
@Styles.Render("~/Content/kendocss")
@Scripts.Render("~/bundles/modernizr")

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/kendo")

Ahora, un sencillo modelo:

public class Values
{
	public int Id { get; set; }

	public int Value { get; set; }

	public DateTime Date { get; set; }
}

Luego en el controlador retornamos una colección de elementos:

public class HomeController : Controller
{
	private List<Values> values = new List<Values>() 
	{ 
		new Values (){ Id = 1, Date = DateTime.Now, Value = 10},
		new Values (){ Id = 2, Date = DateTime.Now.AddMinutes(10), Value = 5},
		new Values (){ Id = 2, Date = DateTime.Now.AddMinutes(20), Value = 15},
		new Values (){ Id = 2, Date = DateTime.Now.AddMinutes(30), Value = 0},
		new Values (){ Id = 2, Date = DateTime.Now.AddMinutes(40), Value = 20}
	};

	public ActionResult Index()
	{
		return View(values);
	}
}

Y finalmente la vista:

@using Kendo.Mvc.UI;
@model IEnumerable<KendoUIChartMvcWrapper.Models.Values>

@{
    ViewBag.Title = "Index";
}

@(Html.Kendo().Chart(Model)
    .Name("chart")
    .Title("Kendo UI Chart")
    .Legend(legend => legend
        .Position(ChartLegendPosition.Bottom)
    )
    .ChartArea(chartArea => chartArea
        .Background("transparent")
    )
    .SeriesDefaults(seriesDefaults =>
        seriesDefaults.Line()
    )
    .Series(series =>
    {
        series.Line(model => model.Value)
            .Name("Cantidad")
            .Labels(true)
            .Opacity(0.8);
    })
    .CategoryAxis(axis => axis
        .Categories(model => model.Date)
        .MajorGridLines(lines => lines.Visible(false))
        .Labels(labels => labels.Rotation(-90))
        .Date()
        .BaseUnitStep(10)
        .MinorGridLines(lines => lines.Visible(true))
    )
    .Tooltip(tooltip => tooltip
        .Visible(true)
        .Format("{0}")
    )
)

En la vista hacemos uso del helper Html.Kendo().Chart(Model) y simplemente le pasamos el modelo que estamos usando, que en este caso es una colección de elementos, luego solo parametrizamos algunas propiedades del helper como el nombre (Name), el título (Title) entre otras…. y finalmente el resultado:

chart kendo

Espero les sea interesante, saludos!