Me acabo de enterar que por tercer año consecutivo Microsoft me han reconocido como MVP en la especialidad de ASP.NET-IIS, este reconocimiento para mi es un gran honor que me motiva cada día a seguir aportando mi granito de arena a la gran comunidad .NET y que de vez en cuando nos reunimos para compartir nuestros conocimientos.
Una cosa que me sorprende cada día más, es que muchos de mis compañeros y eso es extrapolable a toda la red, no conocen que es un Microsoft MVP y eso me sorprende porque la comunidad está plagada de recursos que han aportado estos perfiles y la colaboración en muchos foros tecnológicos.
Eso me da que pensar que existen una gran cantidad de profesionales que realmente no se preocupan por investigar más allá de lo que necesitan en su día a día, o que no tienen ese gusanito que te obliga a aprender nuevas tecnologías aunque realmente no las necesites actualmente para tu trabajo. Y es que en estos años he llegado a escuchar de todo sobre los MVP, que si son los que tienen todos los certificados de Microsoft, que es un certificado especial que se puede comprar, etc.
Por ese motivo me gustaría aclarar algunos puntos sobre este tema:
¿ Qué es un Microsoft MVP ?
Para empezar el reconocimiento MVP "Most Value Profesional" es un premio que otorga Microsoft a Profesionales independientes que consideran lideres excepcionales de la comunidad y que comparten con los demás su pasión, habilidad técnica y conocimiento práctico sobre los productos de Microsoft.
Microsoft da este premio para valorar la aportación de una persona durante todo un año a la comunidad bajo sus criterios de selección y que pasan por un líder MVP territorial y que después es definitivamente aprobado por el equipo de producto en Microsoft Corporation "Redmond" de la especialidad en la que se le ha propuesto.

En la actualidad son ya más de 4.000 los MVP que hay en todo el mundo. Representan a más de 90 países, hablan más de 40 idiomas, responden a más de 10 millones de preguntas al año y se les ha distinguido en casi 90 tecnologías de Microsoft. mas...
Qué no es un MVP
Los MVP son profesionales independientes y por consecuencia un MVP no es ni un trabajador de Microsoft , ni un certificado especial, ni nada que tenga que ver con conseguir el reconocimiento con un examen o por la compra de ningún producto Microsoft.
Como ser MVP
Ser un MVP no puede ser nunca un objetivo, tiene que ser la consecuencia de la dedicación a la comunidad. Este premio es un reconocimiento a una trayectoria dentro de la comunidad y es contraproducente tanto para la persona como para la comunidad solo participar para conseguir este reconocimiento ya que se pierde toda visión imparcial y se pierde la efectividad cuando se trata de ayudar a los demás.
Conseguir esta distinción no es sencillo: entre los más de 100 millones de miembros de la comunidad técnica y social de todo el mundo, solo se reconocen en torno a 3.800 MVP cada año.
Mi consejo es participar en la comunidad activamente y no pensar en el premio. cualquiera puede llegar a convertirse en MVP y cualquiera puede proponer a alguien que crea que se lo merece para que Microsoft lo tenga en cuenta para las siguientes nominaciones.
Puedes proponerte a ti mismo u a otras personas en http://mvp.microsoft.com/es-es/nominate-an-mvp.aspx
Conclusión
Yo solo puedo estar orgulloso de ser reconocido con este premio por Microsoft, pero sobre todo estoy orgulloso de participar activamente en la comunidad y crecer profesionalmente con ella y rodeado de tantos amigos virtuales y presenciales. Gracias a todos.
Cross-Posting: http://mrubino.net
Lo prometido es deuda y os dejo el Material del #JQueryIO que hemos realizado de http://www.desarrolloweb.com espero que lo disfrutéis y me comentéis todas las dudas que os salgan.
Este ha sido un año de grandes cambios y experiencias, soy consciente que he tenido olvidado un poco el blog pero eso me ha dejado un poco más de tiempo para participar más intensamente con las comunidades.
Por eso este año he podido conocer más gente en persona o desvirtualizar a otras tantas que tanto hemos coincidido por la red.
Una de mis buenas intenciones para este año, como la de aprender ingles será volver a retomar el blog técnico como anteriormente y poder ofrecer mi granito de arena a la comunidad explicando mis experiencias en el desarrollo de aplicaciones.
Además agradecer a la gente de CampusMVP por ofrecer algunas de mis entradas al mundo anglosajón y de esa manera ampliar un poco mis horizontes virtuales :-)
Otro gran cambio que he sufrido en este año ha sido el reto de formar parte del equipo de Pasiona Consulting y formar parte de Techdencias dándome la oportunidad de participar más activamente en eventos tecnológicos rodeado de un gran equipo de profesionales como son Toni Recio, Quique Martínez, Eduard Tomàs , Isabel Cabezas, Fernando Escolar, Pablo Bouzada, Roger Bardomà, Alex Casquete, Edin Kapic, Jaume Vinyes. Un equipo increíble !!!
Espero que este año como mínimo me vaya igual que este que dejamos hoy.
Hackathon & Meghaton Windows 8


We Love JS

TechDay Madrid


AndorraDotNet

BcnDevConf

Windows Server 2012 Road Show “Sevilla”

Feliz 2013 !!!
Una de las novedades que nos encontraremos a la hora de afrontar una aplicación Windows Store app , es que la mayoría de veces que interactuemos con sus APIS tendremos que hacerlo de forma asíncrona. De esta manera nuestra aplicación no afectará de forma directa al sistema y la respuesta ante el usuario será más ágil y rápida.
Un ejemplo muy gráfico sería acceder a un fichero del sistema:
Windows.Storage.FileIO.readTextAsync(fichero).then(function (contenido) {
//Mostrar contenido
});
En este ejemplo hemos utilizado la API WinRT para poder acceder al contenido de un fichero de forma asíncrona. En cuanto se accede al contenido del fichero se lanza la función anónima que está dentro del “then” mientras la ejecución de nuestra aplicación ha continuado. De esta manera solo mostraremos el contenido del fichero si hemos podido acceder al mismo sin bloquear la aplicación.
Por convención los nombres de las funciones asincrónicas terminan en "Async". De esta manera puedes saber que la ejecución se producirá después que se devuelva la llamada.
Habitualmente se utilizan llamadas asíncronas para los procesos como:
- Mostrar un cuadro de diálogo de mensaje
- Trabajar con el sistema de archivos
- Enviar datos a Internet y recibirlos
¿Cómo funcionan las llamadas asíncronas en las Windows Store app?
Para trabajar de forma asíncrona tanto WinRT com WinJS utilizan el patrón Promise. Este patrón se puede utilizar para gestionar las llamadas asíncronas de una manera facil de seguir y encadenar.
Un objeto Promise devolverá un resultado en algún momento en el tiempo, por ejemplo la función then nos permitirá actuar cuando la promesa se cumpla y para eso disponemos de tres parámetros.
promise.then( onComplete, onError, onProgress);
- onComplete : función que se lanza cuando se cumple la promesa.
- onError : función que se lanza cuando hay un error.
- onProgress : función que se lanza cuando se notifica un cambio en el progreso de la promesa.
Siguiendo con el ejemplo anterior veremos como capturar los errores y las notificaciones de progreso.
Windows.Storage.FileIO.readTextAsync(fichero).then(
function complete(res) {
document.getElementById("result").textContent = res;
},
function error(res) {
document.getElementById("error").textContent = "Error";
},
function progress(res) {
document.getElementById("progress").textContent = "Progress";
});
Otra función que podemos utilizar es done.
promise.done(onComplete, onError, onProgress);
La diferencia es que en el caso de un error en el procesamiento, la función then devuelve un objeto promise en el estado de error pero no inicia una excepción. Mientras que el método done inicia una excepción si no se proporciona una función de error.
Además then devuelve una promesa lo que nos permite el encadenamiento de promesas, mientras que done devuelve undefined. Por eso se recomienda usar then para una etapa intermedia de la operación (por ejemplo .then().then()) y done para la etapa final de la operación (por ejemplo, .then().then().done()).
Encadenamiento de Promise
Como then devuelve una promesa, puedes encadenar mas de una función asíncrona para su ejecución.
var divResultado = document.getElementById("result");
WinJS.xhr({ url: "http://localhost:32999/api/values" })
.then(function (result) {
divResultado.innerText = result.responseText;
return result;
})
.then(function (result) {
divResultado.style.backgroundColor = "green";
},
function (error) {
divResultado.style.backgroundColor = "red";
divResultado.innerText = "Error";
});
En este ejemplo se puede comprobar como realizar una llamada asíncrona a un servicio de datos externo, en el primer then trataremos los datos, el segundo then destacaremos en la interfaz que los datos se han cargado correctamente y luego tendremos una función para tratar las excepciones.
Es recomendable encadenar las promesas y no anidarlas para una mejor lectura del código y un mejor seguimiento de los errores.
Si lo preferimos podemos tener una función global para el tratamiento de los errores.
WinJS.xhr({ url: "http://localhost:32999/api/values" })
.done(function (result) {
divResultado.innerText = result.responseText;
});
WinJS.Promise.onerror = function errorhandler(event) {
var ex = event.detail.exception;
var promise = event.detail.promise;
};
Pero si utilizamos el evento onerror para capturar el error en tiempo de ejecución, estaremos limitando un poco el control de los errores de las llamadas asíncronas.
Por último hay que tener en cuenta que para procesos muy largos la mejor opción es utilizar tareas en segundo plano.
Para más información visitar la página oficial de msdn donde hay gran cantidad de información y ejemplos sobre el desarrollo de aplicaciones Windows Store App
cross-posting: http://mrubino.net
Update: 22/10/2012
Por si no queda muy claro, Promise no hace que nuestro código sea asíncrono. Promise es una implementación del Patrón Observable y nos ayuda a gestionar nuestras llamadas asíncronas de una manera más sencilla. Las funciones asíncronas son las própias de WinRT acabadas en "Async".
Con la llegada del nuevo sistema operativo de Microsoft, se nos abre un inmenso abanico de posibilidades a los desarrolladores web que no podemos desaprovechar. Ya que podemos crear estas nuevas aplicaciones con HTML 5 y JavaScript para que corran de forma nativa en la nueva interfaz. De esta manera podremos reutilizar todos nuestros conocimientos y nuestra experiencia en realizar aplicaciones que podrán ser consumidas directamente por millones de usuarios potenciales gracias a la nueva tienda de Windows.
Lo primero que tenemos que tener claro es que las aplicaciones web pueden ejecutarse en dos contextos diferentes.
-
El usuario puede abrir la aplicación web desde el navegador que más le guste como se ha realizado siempre. Y la aplicación se ejecutara en un entorno limitado donde no se podrá acceder a las nuevas Apis que ofrece el sistema “WinRT, WinJS”.
-
El usuario ejecutara una aplicación de la App Store realizada con HTML y javascript, en este caso la aplicación se ejecutará de forma nativa y en un contexto local. Tenemos acceso a las Apis del sistema para disfrutar de todas las ventajas que nos ofrece Windows 8 accesible directamente desde nuestro código JavaScript.
Si ya tenemos claro estos dos escenarios, tendremos que adaptar un poco nuestras aplicaciones web para que funcionen correctamente como aplicación nativa en Windows8.
Por ejemplo si queremos consumir un servicio externo de datos “cross-domain” sin problemas, podemos utilizar la librería WinJS para hacer una llamada XmlHttpRequest de forma asíncrona y recuperar estos datos de una forma muy sencilla.
WinJS.xhr({ url: "http://localhost:32999/api/values" }).then(
function (response) {
var json = JSON.parse(response.responseText);
json.forEach(function (item) {
items.push(item);
}
);
} );
Este ejemplo accede a un servicio WebApi que retorna una lista de datos en formato JSon, hay que destacar que está utilizando el patrón Promise para realizar la llamada de forma asíncrona como casi siempre que interactuemos con las Apis de Windows 8.
Los parámetros que acepta esta función son:
- type: (opcional). Especifica el Verbo HTTP a utilizar GET, POST, HEAD “petición sin cuerpo de mensaje”. Por defecto la llamada es GET.
- url: URL del servicio de Datos.
- user: (opcional). String con el nombre de usuario para la autentificación.
- password: (opcional). String con la contraseña para la autentificación.
- headers: (opcional). Objeto cuyas propiedades se usan como nombres de encabezado y los valores de las propiedades se utilizan como valores de estas propiedades del encabezado.
- data: (opcional). El objeto que se pasa como datos en la llamada.
- customRequestInitializer: (opcional). Función para utilizar antes de lanzar la llamada XmlHttpRequest.
Un ejemplo de una llamada estableciendo un parámetro en la cabecera, para asegurarse que la respuesta no está cacheada.
WinJS.xhr({
url: " http://localhost:1489/api/demo ",
headers: {
"If-Modified-Since": "Mon, 27 Mar 1972 00:00:00 GMT"
}
})
.done(function complete(result) {
...
});
Para más información sobre las propiedades que acepta la cabecera visitar HTTP Response Headers:
Y para finalizar veremos un ejemplo completo de una llamada a un servicio de datos enlazado a un ListView:
-
-
El origen de los datos que consulta al servicio: Un fichero Datos.js donde se especifica un espacio de nombres “Data” que utilizaremos más adelante para enlazar los datos con el control.
(function () {
var items = new WinJS.Binding.List();
WinJS.xhr({ url: "http://localhost:1489/api/demo" }).then(
function (response) {
var json = JSON.parse(response.responseText);
json.forEach(function (item) {
items.push(item);
}
);
}
);
var publicMembers = { Modelos: items };
WinJS.Namespace.define("Data", publicMembers);
})();
2. Enlazamos los datos al control de lista de forma declarativa:
<div id="lista" data-win-control="WinJS.UI.ListView"
data-win-options=" {
itemDataSource : Data.Modelos.dataSource,
layout:{type: WinJS.UI.GridLayout}
}" >
</div>

Con este sencillo ejemplo podemos comprobar que sencillo es recuperar los datos de un origen externo sin tenernos que preocupar por el cross-posting ya que se ejecuta la llamada en el contexto local y además se enlaza los datos de forma declarativa con nuestro control HTML.
Cross-Posting: http://mrubino.net
La idea de esta entrada es demostrar lo fácil que puede ser trabajar usando TDD con JavaScript desde nuestro Visual Studio como cualquier otro proyecto de test que tengamos en nuestra solución.
Para este ejemplo utilizaré una aplicación ASP.NET MVC con QUnit el framework de test unitarios que utiliza JQuery y para lanzar los test utilizo directamente Resharper como cuando utilizo otros frameworks como NUnit, MSTest, etc. Debo aclarar que para Visual Studio hay un test runner que lo podéis descargar desde Chutzpah si no tenéis la oportunidad de utilizar Resharper que personalmente me encanta.
Tanto para instalar QUnit como Chutzpah podemos utilizar Nuget desde nuestro proyecto.

TDD
La idea es que necesitamos un Objeto cliente que le podamos especificar diferentes propiedades como puede ser el Nombre, dirección y además añadir sus pedidos.
Test 1
Siguiendo el desarrollo guiado por pruebas, lo primero que tenemos que hacer es una prueba donde intentaremos definir el nombre del cliente.
Lo primero que necesito es poder crear un variable cliente para las pruebas y poderlo utilizar en todas las pruebas y comprobar que cumple con los requisitos. Para eso creo un contexto donde se agruparan todos los test y compartirán la variable cliente. Para esto utilizaré la función module de la librería QUnit.
02 |
module("Client TDD", { |
04 |
this.Client = new Client(); |
05 |
this.Client.Name = "Marc"; |
07 |
teardown: function () { |
Esta función necesita primero el nombre del contexto y luego el objeto usado como el entorno del test. El objeto testEnvironment tiene una función setup que se lanza antes de cada test y podemos utilizar para crear las propiedades que necesitemos utilizar a lo largo de los múltiples test que utilicemos y un teardown que se ejecuta después de cada test que podemos utilizar para limpiar los datos.
Ahora si que podemos crear nuestro primer test.
1 |
test("Test Set Client Name", function () { |
2 |
equal("Marc", this.Client.Name, "el nombre es Marc"); |
Esta primer test comprueba si el cliente contiene una Propiedad Nombre y si su valor es “Marc” para eso utilizaremos una comprobación de igualdad “equal”.

Yo como he comentado antes utilizaré Resharper para lanzar mis Test. El resultado del primer test tiene que ser negativo como no podía ser de otra manera utilizando TDD.
Resharper nos abrirá un el navegador con el QUnit Test Suite, además de mostrarnos el resultado en nuestro Visual Studio.

Los Errores son clarísimos no tenemos creado el objeto Cliente:
- Setup failed on Test Set Client Name: ‘Client’ no está definido.
- Died on test #2: No se puede obtener valor de la propiedad ‘Name’: el objeto es nulo o está sin definir.
Pues ahora nos toca implementar el objeto que la prueba necesita para ser pasada con éxito.
Utilizaré un nuevo fichero javascript donde tendré el código que utilizaré en la aplicación y crearé un objeto cliente utilizando el patrón module, con una parte privada y otra pública.

1 |
var Client = function () { |
Tenemos que añadir la referencia al script del código en el fichero donde se encuentran los test y ya podemos relanzar la prueba.
3 |
module("Client TDD", { . . . |

Todo Verde !!! El objeto Cliente ya está cogiendo forma y todo guiados inicialmente por una prueba de lo que esperábamos que fuera.
Test 2
Siguiendo con la definición de nuestro objeto ahora queremos poder definir una propiedad dirección que será objeto un poco más complicado.
01 |
module("Client TDD", { |
03 |
this.Client = new Client(); |
04 |
this.Client.Name = 'Marc'; |
05 |
this.Client.Address = { |
08 |
PostalCode: '08001' }; |
1 |
test("Test Set Address", function () { |
2 |
equal({ street: "Gran Via", state: "Barcelona", PostalCode: "08001" }, |
4 |
'The address is { street: "Gran Via", state: "Barcelona", PostalCode: "08001" }'); |

Como antes hasta que no añadamos esta propiedad al objeto cliente no pasará la prueba correctamente,
3 |
_public.Address = { street: "", state: "", PostalCode: "" }; |
Pero el test vuelve a fallar !!!

El test falla porque estamos comparando dos objetos que aunque tengan todas las propiedades con el valor igual, son dos objetos diferentes. Par este caso no nos sirve un simple equal y tendremos que hacer una comparación más profunda que nos servirá para objetos y arrays con deeEqual.
1 |
test('Test Set Address', function () { |
2 |
deepEqual({ street: 'Gran Via', state: 'Barcelona', PostalCode: '08001' }, |
4 |
'The address is { street: "Gran Via", state: "Barcelona", PostalCode: "08001" }'); |

Test 3
Ahora nuestra intención es hacer un Get-Set y un Count de los pedidos del cliente.
01 |
test('Test Set.Get Orders', function () { |
02 |
this.Client.Set_Order({ Id: "12345", Name: "Rent Car", Total: 237.45 }); |
05 |
{ Id: "12345", Name: "Rent Car", Total: 237.45 }, |
06 |
this.Client.Get_Order(1), |
07 |
'The order is { Id: "12345", Name: "Rent Car", Total: 237.45 }'); |
08 |
strictEqual(2, this.Client.Orders(), 'The client have 2 orders'); |
Como siempre en TDD la primera prueba falla porque falta definir las funciones en el objeto cliente.

Ampliamos el objeto y pasamos la prueba:
1 |
_public.Set_Order = function (order) { |
2 |
_private.Orders.push(order); |
4 |
_public.Get_Order = function (index) { return _private.Orders[index]; }; |
5 |
_public.Orders = function () { return _private.Orders.length; }; |

Lo que hay que destacar de este test es que hemos definido dos pruebas en el mismo test con expect(2) y hemos hecho una comprobación estricta con resultado y tipo en el count con strictEqual.
Ya tenemos nuestro objeto completo y podríamos seguir con TDD por ejemplo haciendo alguna prueba asíncrona con asyncTest , pero si necesitáis más información sobre QUnit podéis consultar su documentación en http://docs.jquery.com/QUnit
Conclusión
Ya no tenemos excusa para no tener nuestro código JavaScript cubierto con pruebas unitarias garantizando la calidad y un código más mantenible. Con TDD podemos crear nuestros objetos javascript desde nuestros requerimientos y tener directamente garantizado su correcto funcionamiento a partir de nuetros requisitos y necesidades establecidas.
Cross-Posting: http://mrubino.net
Este truco es uno de los top10 en los foros de MSDN y sigue siendo una de aquellas cosas que no es fácil encontrar una documentación clara y adecuada.
Si hablamos desde la perspectiva de ASP.NET MVC esta tarea se nos simplifica muchísimo porque desde nuestro controlador podemos devolver directamente el contenido de un fichero como cualquier otro ActionResult que tengamos configurado. Para eso tenemos el método File que nos proporciona esa funcionalidad y no tenemos que utilizar directamente el objeto Response como nos pasaba con el clásico ASP.NET WebForms.
1 |
FileContentResult File(byte[] fileContents, string contentType) |
2 |
FileContentResult File(byte[] fileContents, string contentType, string fileDownloadName) |
3 |
FileStreamResult File(Stream fileStream, string contentType) |
4 |
FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName) |
5 |
FilePathResult File(string fileName, string contentType) |
6 |
FilePathResult File(string fileName, string contentType, string fileDownloadName) |
Para este ejemplo utilizaré la sobrecarga que retorna un FileStreamResult porque lo que queremos hacer es:
Un servicio que recupere los datos de nuestro repositorio, serialice nuestra entidad del dominio en un XML directamente en memoria. Devuelva su contenido especificando que es un fichero Excel y el nombre del fichero que se utilizará para guardar.
Todo esto lo generará dinámicamente en memoria sin tener que tener el fichero Excel físicamente en nuestro servidor.
01 |
public ActionResult ObtenerMisEnviosXmlExcel() |
03 |
_productosServices = new ProductosServices(); |
04 |
var stream = new MemoryStream(); |
05 |
var serialicer = new XmlSerializer(typeof(List)); |
08 |
List datos = _productosServices.GetProductos(); |
11 |
serialicer.Serialize(stream, datos); |
15 |
return File(stream, "application/vnd.ms-excel", "Pedidos.xls"); |
Para poder serializar nuestra entidad del dominio utilizaremos la clase XmlSerializer que se encuentra en el namespace System.Xml.Serialization.
Cada vez que realicemos esta llamada nos devolverá el fichero Excel creado al vuelo con los datos recuperados de nuestro repositorio.

Una cosa que hay que tener en cuenta al realizar la serialización en XML, es que no es el formato estándar de Excel y tiene que abrir el fichero como datos XML. Eso implica que al abrir el fichero lance un par de avisos que son un poco incómodos más que otra cosa.

He estado probando diferentes librerías para crear ficheros Excel, pero todos te permiten montando el documento por programación, pero no montarlo automáticamente dependiendo de los datos cargados como es el caso del ejemplo anterior.
Si alguien conoce alguna librería que sea capaz de hacerlo directamente o tiene alguna experiencia parecida le invito a que la comparta para poder ampliar esta información y que nos sea de utilidad a todos.
Os recuerdo que también tenéis una entrada relacionada para generar un PDF al vuelo directamente desde una de nuestras vistas recuperando su HTML.
Cross-Posting: http://mrubino.net
Este miércoles 23 de Mayo se celebra en Barcelona el encuentro mensual que organiza el grupo WebCat "Barcelona web professionals". En estas reuniones se realizan micro sesiones de diferentes tipos y niveles pero con el punto en común que nos une a todos los que trabajamos en entornos orientados a la web.
Micro Sesiones:

Lugar 23 mayo de 7pm a 9pm en Providència, 88, Barcelona. Para más informaciñon http://lanyrd.com/2012/webcat-may
Nos Vemos ;-)

Desde que asistí al Hack-a-thon de Fuengirola sobre Windows Phone, mi intención ha sido aprovechar la cuenta de suscriptor y publicar algún tipo de aplicación.
Le estuve dando muchas vueltas a que tipo de aplicación podría realizar, mi primera intención era hacer una brújula que apuntara a la Meca para que los musulmanes lo tuvieran más fácil a la hora de orientarse, pero mi sorpresa fue mayúscula cuando me di cuenta que ya habían un par de aplicaciones de este tipo y además una era de pago. A partir de ese momento entendí que cualquier idea que pudiera tener seguro que ya estaba publicado en el MarketPlace.
Pero no desistí en el intento y se me ocurrió hacer un juego en XNA, si tengo que empezar de cero a programar para Windows Phone que mejor que hacer un juego en XNA que no una aplicación con Silverligth que no me gusta nada.
Bueno ya tenía la base y ahora pensar en el juego. Ummm mi primer juego y sin tener ni idea de XNA no puede ser muy complicada de desarrollar. Que mejor que empezar con un clásico que no tiene muchas pantallas y que seguro no puede ser muy difícil de programar como es el Space Invaders.
Cuando tomas una decisión como la mía es ir a la página de Microsoft donde puedes encontrar los ejemplos de todo lo que necesitas para desarrollar tu aplicación.
La Base para el Juego:
- Pantallas de la aplicación
- Inicial
- Juego Principal
- Menú Pausa
- Fin de Partida
- Un fondo que no se tiene que animar
- Una entidad Nave para el jugador principal
- Movimiento de derecha a izquierda
- Disparo “sonido de disparo”
- Explosión para cuando es alcanzado y Sonido explosión
- Una entidad Enemigo para crear todos los enemigos con esta base.
- Movimiento de izquierda a derecha “pero en bloque”
- Diferentes puntuaciones por tipo de enemigo
- Disparo
- Explosión al ser alcanzado y sonido
- Diferentes niveles para hacer durar un poco el juego
- Recursos para mostrar las vidas, puntuación y record

¿ Como una persona que nunca ha creado un juego, ni a programado en XNA puede salir exitoso de esta experiencia ?
Yo por ejemplo para mi primer contacto con el tema, miré el curso de un juego con XNA llamado Shootter.

Existe una página web sobre desarrollo en Windows Phone indispensable para todo aquel que quiera introducirse en este mundo con gran cantidad de ejemplos que podremos utilizar en nuestros desarrollo.
Pero tener cuidado no tengáis la tentación de publicar directamente el ejemplo de Microsoft como si fuera vuestro que ya no seríais los primeros XD.
Después de esta experiencia que realmente he aprendido mucho he decidido pasar el juego a HTML5 y JavaScript para poderlo utilizar en diferentes plataformas, ya os informaré como me va y si la experiencia es igualmente positiva “seguro que si”.
No os olvidéis de descargar y probar mi juego ;-)
http://www.windowsphone.com/es-ES/apps/c2b100ff-45d8-4972-9d33-8bcbc2f148ba
El sábado que viene día 28 de Abril, se celebra en Barcelona un encuentro de los profesionales en desarrollo web que apreciamos lo que significa javascript, lo hemos sufrido como todo el mundo, pero también sabemos valorar todo lo que nos aporta. Este evento es organizado por Agile-Barcelona, Runroom y Softonic, un evento de mañana y tarde .
Agenda
10:00 – 11:00 APRETURA – RECEPCIÓN
11:00 – 11:30 Charla sobre CoffeeScript
12:00 – 12:30 Networking
12:30 – 13:30 Charla sobre Game Development
13:30 – 15:00 COMIDA (cortesía de Softonic)
15:00 – 18:00 Workshop Backbone.js
15:00 – 18:00 Workshop PhoneGap.js
* Importante: Los workshops son en paralelo, de modo que te rogamos que únicamente saques ticket en uno de los dos.
Si tenéis pensado asistir daros prisa que solo quedan pocas plazas, yo ya me he registrado ;-)
http://welovejs.es
Segundo año consecutivo que he recibido la grata noticia desde Microsoft que he sido nombrado nuevamente Microsoft MVP en ASP.NET / IIS para este 2012.
Enhorabuena. Nos complace presentarle el programa de nombramiento MVP de Microsoft® de 2012. Este nombramiento se concede a los líderes excepcionales de la comunidad técnica que comparten de forma activa su experiencia de alta calidad y de la vida real con otras personas. Le agradecemos especialmente la contribución que ha realizado en las comunidades técnicas en el área de ASP.NET/IIS a lo largo del pasado año.
La verdad que es una experiencia inolvidable poder participar en esta comunidad y que se te valore por ello, pero lo más importante y con lo que realmente me quedo es con las personas que he conocido durante todos estos años y que me han ayudado siempre que lo he necesitado y nunca me ha faltado su apoyo. Si los tuviera que nombrar a todos seguramente me dejaría a alguno, pero desde aquí si que me gustaría nombrar a dos personas muy activas en la comunidad que este año se han quedado sin reconocimiento por parte de Microsoft, pero estoy seguro y conociendolos muy bien, sé que ellos seguirán aportando y ayudando a todo el mundo que lo necesite y seran nuevamente nombrados MVP. Un saludo muy fuerte para Toni Recio y José Miguel Torres.
Espero poder seguir aportando mi granito de arena y agradecer a Microsoft este reconocimiento.

Cross-Posting: http://mrubino.net/
Una aplicación ASP.NET sobre IIS escala muy bien y tiene muy buen resultado cuando hablamos de peticiones por segundo, pero la cosa puede mejorar cuando hablamos de conexiones concurrentes.
Teniendo en cuenta que cada vez más nuestras aplicaciones son asíncronas, está aumentando la cantidad de peticiones que nuestra aplicación tiene que soportar .
Por defecto ASP.NET 4.o acepta 5.000 peticiones concurrentes por CPU
Peticiones concurrentes por CPU:
Una aplicación ASP.NET en modo integrado bajo IIS7 nos permite configurar cómo administrar los subprocesos y como poner en cola las solicitudes cuando la aplicación está hospedada en un grupo de aplicaciones de IIS.
Los valores applicationPool se aplican a todos los grupos de aplicaciones que se ejecutan en una versión determinada de .NET Framework. La configuración está contenida en un archivo aspnet.config. Hay una versión de este archivo para las versiones 2.0 y 4 de .NET Framework. (Las versiones 3.0 y 3.5 de .NET Framework comparten el archivo aspnet.config con la versión 2.0.)
- maxConcurrentRequestPerCPU: Especifica cuántas solicitudes simultáneas permite ASP.NET por CPU.
- maxConcurrentThreadsPerCPU: Especifica cuántos subprocesos simultáneos se pueden estar ejecutando para un grupo de aplicaciones para cada CPU. Esto proporciona una manera alternativa de controlar la simultaneidad de ASP.NET, ya que puede limitar el número de subprocesos administrados que se pueden usar por CPU para atender las solicitudes. De forma predeterminada este valor es 0, lo que significa que ASP.NET no limita el número de subprocesos que se pueden crear por CPU, aunque el grupo de subprocesos de CLR también limita el número de subprocesos que se pueden crear.
- requestQueueLimit: Especifica el número máximo de solicitudes que se pueden poner en cola para ASP.NET en un único proceso. Cuando dos o más aplicaciones ASP.NET se ejecutan en un único grupo de aplicaciones, el conjunto acumulativo de solicitudes que se realizan a cualquier aplicación del grupo de aplicaciones está sujeto a este valor.
Para configurar nuestra aplicación que trabaja con el framework 4.0 x64
- fichero de configuración :
%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet.config
- Modificar el fichero
3 |
<applicationPool maxConcurrentRequestsPerCPU="5000" |
4 |
maxConcurrentThreadsPerCPU="0" requestQueueLimit="5000" /> |
Peticiones concurrentes por Aplicación:
Si lo que queremos es controlar la peticiones concurrentes por aplicación nos tendremos que ir a la configuración serverRuntime de nuestro servidor IIS.
- appConcurrentRequestLimit: Especifica el número máximo de solicitudes que pueden poner en cola para una aplicación. El valor predeterminado es 5.000.
Modificamos la configuración del servidor:
- Abrimos el fichero de configuración:
%windir%\System32\inetsrv\config\applicationHost.config
- Buscar el elemento
serverRuntime
- Modificar la propiedad
appConcurrentRequestLimitque por defecto son 5.000
1 |
<serverRuntime appConcurrentRequestLimit="250000" /> |
Además se puede controlar el tamaño de las cola que utiliza ASP.NET cuando se supera la cantidad de solicitudes por CPU estableciendo requestQueueLimit de processModel.
1 |
<processModel autoConfig="false" requestQueueLimit="250000" /> |
Con todas estas modificaciones podemos controlar mucho mejor el rendimiento de nuestra aplicación y potenciar la gran cantidad de peticiones que se verán incrementadas con el uso de peticiones asíncronas.
Cross-Posting: http://mrubino.net
Por primera vez he podido asistir al evento anual que organiza Microsoft dedicado a los MVP de todo el mundo llamado MVP Summit 2012.
Miles de personas reunidas con un mismo objetivo y con la posibilidad de ver las instalaciones que tiene Microsoft en Redmond.
Mi experiencia a este aspecto es totalmente positiva, poder estar una semana con mis colegas y conocer a gente de todo el mundo y especialmente al grupo de Españoles + Andorra, con los que pasé muy buenos momentos. Poder conocer a los integrantes del equipo de producto es otra oportunidad que no se puede explicar.
Nos hablaron de las novedades que se han lanzados durante estos días sin realmente darnos ninguna noticia bomba y pudimos jugar con las nuevas betas a la vez que el resto del mundo.
Está claro que si Microsoft me vuelve a reconocer con el nombramiento MVP nuevamente, no dejaré de asistir a esta convocatoria porque realmente vale la pena.
Y como una imagen vale más que mil palabras…




La ventaja de utilizar sprites para nuestros efectos con imágenes, es que no tenemos que esperar a que las imágenes se carguen individualmente, ya que solo tendremos una imagen principal para obtener el mismo efecto.
Piensa la cantidad de descargas que tiene que efectuar el navegador para cada una de las pequeñas imágenes que normalmente utilizamos en nuestras webs. Si todas estas pequeñas descargas la disminuimos en una principal reduciremos el tiempo de descarga de la página de una manera considerable.
El ejemplo más utilizado sería los tres estados de un ratón “normal, al pasar por encima con el ratón y al presionar”. Si utilizas tres imágenes independientes el usuario l pasar el ratón por encima del botón puede experimentar un retardo al mostrar la nueva imagen porque el navegador la tiene que descargar. Pero si utilizamos sprite con CSS este efecto indeseado desaparece a la vez que optimizamos la descarga.
Ejemplo 1: Imágenes por separado.
Imagen 1

Imagen 2

Imagen 3

El CSS para dar efecto al botón.
05 |
background: url(../../Content/btn1.png); |
06 |
border: black solid 0px; |
11 |
background: url(../../Content/btn2.png); |
15 |
background: url(../../Content/btn3.png); |
Ejemplo 2: Imagen en Sprite.
Imagen

El CSS para dar efecto al botón.
05 |
background: url(../../Content/btnS.png)0 0; |
06 |
border: black solid 0px; |
11 |
background: url(../../Content/btnS.png)0 135px; |
15 |
background: url(../../Content/btnS.png)0 70px; |
Lo importante de utilizar una sola imagen es poder posicionar el fondo mediante la posición x-y, y jugar con el tamaño . De esta manera se muestra la porción de la imagen que necesitamos en cada momento.
Como se puede observar con las imágenes individuales tenemos tres descargas de 3,3KB que han tardado 48ms y con una imagen tipo sprite tenemos solo una descarga de 8,19KB que se ha descargado en 15ms. Una buena mejora con un simple botón imaginaros si optimizamos todas nuestras imágenes de la página.
Ejemplo 1

Ejemplo 2

Con esto ya tenemos un pasito más para poder tener nuestra web un poco más optimizada y para que veáis que esto es una buena práctica os pongo la colección de iconos que utilizan los controles JQuery UI en sus temas.

Cross-Posting: http://mrubino.net
Una de las utilidades que contamos los desarrolladores web en Visual Studio 2010 y que por mi experiencia veo que no se utiliza mucho. Es la transformación de ficheros de configuración.
A quien no le ha pasado que ha realizado un despliegue al entorno de producción y se ha dejado el modo debug activado o la cadena de conexión a la de test. Pues Visual Studio nos permite poder evitar esto de una manera muy fácil y además automática, para que no nos tengamos que preocupar de si lo hemos configurado todo correctamente para el despliegue.
Ficheros de Transformación
Una de las situaciones que habitualmente nos encontramos en los proyectos, es que tenemos que tener diferentes ficheros de configuración para cada uno de los entornos de los que contamos.
No es lo mismo hacer un despliegue para el entorno de Desarrollo que para Pre-Test o Producción. Por eso ahora disponemos de la posibilidad de modificar el fichero de configuración dependiendo de donde queramos publicar nuestra aplicación web.
Lo primero que tenemos que hacer es crear una configuración de compilación que la podemos definir por ejemplo para cada entorno en el que trabajaremos con las diferentes configuraciones.

Podemos crear una configuración nueva o copiar de otra existente.

Una vez que tengamos las configuraciones creadas, hacemos clic con el botón derecho en el fichero de configuración y añadimos los nuevos ficheros de transformación.

Tendemos que tener tantos ficheros de transformación como diferentes configuraciones necesitemos en nuestros despliegues.

¿Qué son los ficheros de Transformación?
Los ficheros de transformación, son ficheros XML que utilizan los atributos XML para especificar que se tienen que modificar o eliminar del fichero web.config.
Por ejemplo el fichero de transformación de la publicación en Release elimina el famoso atributo Debug=true.
4 |
<compilation xdt:Transform="RemoveAttributes(debug)" /> |
XML-Document-Transform
Este espacio de nombres tiene dos propiedades Principales:
- Locator:Se seleccionan los elementos que coinciden con la expresión XPath combinada.
- Locator=”Match(key)” – Selecciona los elementos que concidan con el atributo key.
- Transform:Especifica la transformación de elemento o elementos seleccionados con la propiedad locator.
- Replace: Sustituye el elemento o primer elemento seleccionado por el informado.
- Insert: Inserta un nuevo elemento como podría ser una nueva cadena de conexión, al final de la colección.
- InsertBefore: Inserta un nuevo elemento justo antes del elemento seleccionado.
- InsertAfter: Inserta un nuevo elemento justo después del elemento seleccionado.
- Remove: Elimina el elemento o primer elemento seleccionado.
- RemoveAll: Elimina todos los elementos seleccionados.
- RemoveAttributes: elimina el atributo especificado de los elementos seleccionados.
- SetAttributes: Modifica los atributos especificados de los elementos seleccionados.
Los ejemplos más utilizados serían:
-
- Modificar el valor de una propiedad personalizada de la configuración por su clave.
1 |
<add key="UrlEscritura" value="http://test/ Solicitudes/ServicioEscritura.svc" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/> |
-
- Modificar una cadena de conexión por su nombre: perfecto si atacamos a diferentes bases de datos en cada entorno.
2 |
<add name="SqlCon" connectionString="Data Source=server;Initial Catalog=test;" providerName="System.Data.SqlClient" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> |
-
- Eliminar el famoso atributo de modo Debug cuando compliamos en Release:
2 |
<compilation xdt:Transform="RemoveAttributes(debug)" /> |
Conclusión
Si nos preocupamos un poco en tener diferentes configuraciones de compilación para nuestros entornos, además de facilitarnos los despliegues y su configuración de forma automática.
También nos evita los típicos errores por descuido que tantos problemas nos suelen dar en los despliegues.
Cross-Posting: http://mrubino.net
Últimamente se está oyendo hablar mucho de SignalR en los en tornos de ASP.Net y no es para menos.
Los programadores web estamos acostumbrados a hacer peticiones al servidor “Pull” para poder consultar cualquier cosa y en más de una ocasión hemos tenido que tirar de un timer en el cliente para que cada X-tiempo consulte un recurso del servidor e ir informando al usuario del progreso de una tarea o de los datos que se tienen que actualizar constantemente.
Para evitar esto podríamos utilizar a día de hoy varias opciones como la API de html5 WebSocket que está en fase borrador y ha tenido algún problema de seguridad, podemos utilizar el servidor Openfire con el protocolo XMPP o servidor Node.js con la librería Nowjs . Pero la ventaja que proporciona SignalR frente los otros es que esta especialmente diseñado para aprovechar las características de las aplicaciones ASP.NET MVC tanto el lado del servidor como la parte cliente.
Como empezar
Para empezar tenemos que instalar la librería que tenemos disponible desde Nuget.

Tienes que tener en cuenta que tiene dependencias con la librería JQuery .

El Servidor
En el servidor solo necesitamos una clase que implemente Hub y si queremos hacer una devolución al cliente solo tenemos que añadir una expresión dinámica a Clients que se resolverá en tiempo de ejecución.
1 |
public class NotificationHub : Hub |
3 |
public void Notificar(string valor) |
5 |
Clients.AddValor("Informamos al cliente"); |
El cliente
Recordar la dependencia con JQuery y además hay que poner una referencia a “/Signalr/Hubs” que es donde se crearan los scripts dinámicamente para las llamadas al servidor.
1 |
<script type="text/javascript"> |
2 |
src</span>="/Scripts/jquery-1.7.1.js" type="text/javascript"> |
4 |
<script type="text/javascript"> |
5 |
src</span>="/Scripts/jquery.signalR.js" type="text/javascript"> |
7 |
<script type="text/javascript"> |
8 |
src</span>="/Signalr/Hubs" type="text/javascript"> |
1 |
$.connection.hub.start(); |
2 |
var hub = $.connection.notificationHub; |
3 |
hub.AddValor = function (valor) { |
1. Abrimos la conexión con el servidor.
2. Inicializamos nuestro hub donde haremos las llamadas.
3. Definimos la función de devolución para actuar cuando el servidor nos informe.
Ya esta !!!! Es súper sencillo !!!!
EJEMPLO
Haré un pequeño ejemplo para que se vea toda su potencia en acción. Imaginaros un control de encuesta donde sea el servidor el que te informe que sus datos se han actualizado y solo permita votar una vez al usuario, toda la lógica estará en el servidor y no en la UI, de esta manera no mezclamos responsabilidades.
Utilizaré la librería jqplot.js para mostrar la gráfica de la encuesta en tiempo real.
Servidor
Primero crearé la parte del servidor donde estará la lógica de los votos.
01 |
public class NotificationHub : Hub |
03 |
public void Notificar( string valor) |
05 |
if (valor != null && Encuesta.Instance != null |
06 |
&& Encuesta.Datos.ContainsKey(valor)) |
08 |
var clientId = Context.ClientId; |
09 |
if (Encuesta.Usuarios.Any(u => u == clientId)) |
16 |
Encuesta.Usuarios.Add(clientId); |
17 |
Encuesta.Datos[valor]++; |
18 |
var resultado = Encuesta.Datos.Keys.Select( |
23 |
key, Encuesta.Datos[key] |
27 |
Clients.AddValor(resultado); |
Esta clase controla si el usuario ya ha votado y si no lo añade a la lista para no permitir votar la próxima vez que llame el mismo cliente y como se puede observar, tenemos acceso al identificador del cliente para controlar quien es el que hace la llamada, pero además podemos acceder al dentity para hacer un seguimiento más exhaustivo del usuario y sus credenciales.

Luego si el voto es de un elemento correcto le incrementa el número de votos y retorna a todos los clientes conectados los nuevos datos de la encuesta actualizada.
El cliente llamara a Notificar(valor) para informar del voto y estará en espera que el servidor actualice los datos con AddValor(resultado).
Cliente
Tendremos una vista con varios radio buttons para seleccionar las opciones de la encuesta y un botón que lanzara la llamada al servidor con la selección del usuario.
02 |
inicializarEncuesta(); |
03 |
$("#btnSendNotificacion").click(function () { |
04 |
var voto = $('input:radio:checked').val(); |
07 |
$.connection.hub.start(); |
08 |
var hub = $.connection.notificationHub; |
09 |
hub.AddValor = function (valor) { |
10 |
$.jqplot('chart1', [valor], chartOption()).replot(); |
Si el servidor devuelve nuevos datos “AddValor” entonces repintaremos el gráfico con la nueva información.

De esta manera todos los usuarios conectados a la encuesta reciben las actualizaciones en tiempo real.
Conclusión
SignalR es un Framework potente y fácil de utilizar que nos permite mantener conexiones abiertas con el servidor de ASP.NET.
Con este tipo de librerías podemos empezar a realizar aplicaciones realmente colaborativas y en tiempo real, donde se definen mejor las responsabilidades gracias a las llamadas Push y nos ayuda a no agregar lógica de negocios en nuestras UI.
Cross-Posting: http://mrubino.net
En ciertas ocasiones podemos necesitar deserializar un objeto pasado desde un cliente en formato JSon a un tipo .net anónimo. Por ejemplo si utilizas MongoDB con el driver NORM y pretendes filtrar u ordenar de una manera dinámica, es difícil pasar estos objetos a la query para poder generar un filtro dinámico.
Para hacernos una idea esta sería una consulta paginada y con un filtro sencillo con NORM:
2 |
return GetRepository().GetCollection("Personas") |
4 |
new { Nombre = Q.IsNotNull() }, |
5 |
new { Fecha = OrderBy.Descending }, |
Esta consulta nos devolvería las 10 primeras personas con Nombre que no sea null.
Tanto al utilizar los tipos anónimos como en las consultas LinQ se tiene que especificar la propiedad por la que se quiere filtrar u ordenar y eso nos limita a la hora de intentar hacer estas consultas de forma dinámica.
Parara hacer una prueba crearemos un tipo específico para utilizar en las consultas desde javaScript.
Lo ideal sería:
1 |
public class QueryRequest |
3 |
public int Pagina { get; set; } |
4 |
public int Registros { get; set; } |
5 |
public object Orden { get; set; } |
6 |
public object Filtro { get; set; } |
Con este tipo nos pasarían como parámetros lel número de página, la cantidad de registros y además un object para filtrar y otro object para ordenar.
Pero esto no funciona porque NORM no lo reconoce como tipo anónimo y si lo intentamos pasar como string tampoco funciona.
Ahora solo nos queda intentar deserializar directamente nosotros el objeto JSON en un tipo anónimo y para eso utilizaremos el tipo dynamic que tenemos disponible desde c# 4.
Para eso solo tenemos que deserializar un texto con datos en formato JSon utilizandoJavaScriptSerializerque te permite utilizar un tipo T.
1 |
var jss = new System.Web.Script.Serialization.JavaScriptSerializer(); |
2 |
var ObjetoAnonimo = jss.Deserialize(strJson); |
Con estas dos líneas lo tenemos solucionado y el nuevo tipo podría quedar de esta manera para facilitar la entrada de los datos como string y la salida como objeto dinámico.
01 |
public class QueryRequest |
03 |
public int Pagina { get; set; } |
04 |
public int Registros { get; set; } |
08 |
public dynamic Orden { get { return DeserializarJSon(orden); } set { orden = value; } } |
11 |
private string filtro; |
12 |
public dynamic Filtro { get { return DeserializarJSon(filtro); } set { filtro = value; } } |
14 |
private dynamic DeserializarJSon(string strJson) |
16 |
var jss = new JavaScriptSerializer(); |
20 |
resultado = jss.Deserialize(strJson); |
Ahora nuestro objeto es capaz de devolver un tipo anónimo al consultar la propiedad Filtro y Orden.
01 |
public IEnumerable FindFiltradoDinamico( QueryRequest datos ) |
04 |
return GetRepository().GetCollection("Personas") |
06 |
datos.Filtro as object, |
07 |
datos.Orden as object, |
09 |
datos.Pagina * datos.Registros |
Ahora si tenemos las consultas preparadas para aceptar parámetros dinámicos.
01 |
public ActionResult Index() |
03 |
var datos = new QueryRequest() |
07 |
Filtro = " { Edad : { '$gt': 15 } } ", |
08 |
Orden = "{ Nombre : -1}" |
11 |
var f2 = repositoryPersona.FindFiltradoDinamico(datos); |

Cross-Posting: http://mrubino.net
Partiendo de que la intención de MVC es separar las responsabilidades de cada componente, me gustaría explicar cual es la responsabilidad de las vistas y como utilizarlas en ASP.NET MVC.
Lo que primero nos choca a los programadores que procedemos de los formularios web, es que han desaparecido los eventos y el famoso ciclo de vida, y eso se debe precisamente que ASP.NET MVC es mucho más natural en los protocolos HTTP y HTML en su tratamiento.

Mvc vs WebForms
Como se puede apreciar en la imagen los formularios web se basaban en los eventos para procesar una petición, entrar en el ciclo de vida del documento, tratar el evento, pintar los controles y devolver el resultado.
Sin embargo las peticiones en MVC son mucho mas simples y respetuosas con el protocolo HTTP. La petición la recibe el motor de rutas que mediante la URL decide cual es el controlador que la debe procesar, el Controlador puede consultar al modelo si es necesario y posteriormente devuelve un ActionResult que puede ser un fichero, datos en formato JSon, una vista, etc.
Vistas
Como ya he comentado la vista encapsula la lógica de presentación y NO tiene que contener lógica de la aplicación ni código de recuperación de datos.
Las vistas no son ficheros físicos ligados a una URL como en los formularios web. Cuando queríamos consultar un formulario teníamos que poner su ruta física www.miaplicacion/personas.aspx En MVC es el controlador el que decide que vista servir y eso facilita que las url sean descriptivas y que los buscadores puedan indexar mejor las páginas de nuestra aplicación “SEO Friendly“.
ViewBag:
Las vistas pueden recibir datos desde el controlador gracias al ViewBag que devuelve un diccionario de datos dinámicos. La gran diferencia con ViewData de las versiones anteriores de MVC, es que ViewBag aprovecha la opción de c#4 para generar tipos dinámicamente y evita tener que hacer conversiones en la vista para obtener el tipo adecuado de los datos.
En el Controlador: Definimos la propiedad que queremos pasar a la vista y el dato
1 |
ViewBag.Message = "Welcome to ASP.NET MVC!"; |
En la vista: desde la vista recuperamos el dato de una forma muy fácil.
1 |
<h2>@ViewBag.Message</h2> |
ViewData vs ViewBag: la gran diferencia es que ya no tenemos la necesidad de hacer conversiones de los datos para poder tratarlos correctamente
1 |
@*Tipo Fecha con tipos dinámicos*@ |
2 |
<h1>@ViewBag.FechaVieBag.ToShortDateString()</h1> |
5 |
@*Tipo Fecha con ViewData*@ |
6 |
<h1>@(((DateTime)ViewData["Fecha"]).ToShortDateString())</h1> |
Tipos de Vistas de las que disponemos:
- View Page: Vista principal.
-
LayoutView: Pagina Maestra.
-
ViewContentPage: Vista que utiliza una página Maestra predefinida.
-
Partial View: Vista que se utiliza desde otra vista y no se puede llamar directamente. Como se utilizaban los user controls en los webForms. La vista parcial tiene acceso a su ViewData y al dela vista primaria, pero las actualizaciones de los datos de la vista parcial solo afectan a su viewData y no a la de la vista primaria.
View Engines
ASP.NET MVC utiliza view engines para generar las vistas y desde MVC3 disponemos de dos motores de vistas incluidos para utilizar directamente.
-
ASPX: Es el motor de vistas de ASP.NET con tipos personalizados “ViewPage, ViewMasterPage y ViewUserControl” que heredan de los tipos de páginas existentes .aspx, .ascx, .master.
-
Razor: Motor de vistas más cercano para los programadores de C# o VB
-
Otros:
Convenciones
Hay un par de convenciones que nos afectan al trabajar con las vistas y nos ahorran interminables ficheros de configuración.
2 |
public ActionResult Create() |

En esta imagen las extensiones de los ficheros son .cshtml porque he utilizado el motor de vista Razor en C#, si utilizara VB seria .vbhtml y si utilizara el motor de vista ASPX sería (.aspx, .ascx, .Master)
Creo que con esto hemos visto todo lo que tiene que ver con las vistas en MVC 3
Cross-Posting: http://mrubino.net
Os recuerdo que este lunes grabaremos el webCast sobre MVC 3 y Html5 con Visual Studio 2010 con la gente de Auges el grupo de usuarios de ASp.Net Spain.

Después de participar en el Barcelona Developer Conference tengo la oportunidad de repetir evento pero esta ves online y con la posibilidad de hacerla completa y sin las restricciones de tiempo que mormalmente nos encontramos en los eventos presenciales.
Podéis acceder al registro en https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032500294&Culture=es-ES
Ademas recordaros que el Martes desde SecondNug tenéis otro webCast de Lluis Franco MVP de Visual C# sobre Mejorar el rendimiento con programación paralela.

Espero Veros a Todos ;-)
Cross-Posting: http://mrubino.net
Esta semana se ha realizado el primer Barcelona Developer Conference 2011 y espero que no sea la última porque nos ha dejado a todos un gran sabor de boca y una innumerable lista de nuevos contactos.
Tenéis disponible el material y la presentación para que podáis jugar un poco con el ejemplo, ya que no tuvimos mucho tiempo para verlo todo.
Proyecto de Ejemplo : 
Para los que os supo a poco y tenga ganas de ver la charla completa seguro que no tendremos problemas de tiempo en el webCast que haremos el próximo lunes 28 en el grupo de usuarios de ASP.NET Spain
Nos vemos el Lunes
Cross-Posting: http://mrubino.net
Más artículos
Página siguiente >