Consumiendo InternalEndPoint–WCF en Azure

Hola a todos.

Después de crear un wcf en Azure y de consumir un EndPoint interno que viaja por tcp, ahora procedemos a consumir dicho EndPoint interno desde una aplicación en un WebRole.

Para revisar el post anterior http://geeks.ms/rduarte/2016/03/13/comunicacin-interna-wcf-en-azure/

Lo primero es agregar una solución web de tipo Web Role, puede ser una aplicación tipo web forms o mvc.

image

Dicha aplicación le colocamos un EndPoint de entrada, para poder acceder a ella.

image

Creamos un botón con la siguiente funcionalidad.

protected void Button1_Click(object sender, EventArgs e)
		{
			try
			{
				var factory = new ChannelFactory<WcfWorker.IWorker>(new NetTcpBinding(SecurityMode.None));
				var current = RoleEnvironment.CurrentRoleInstance;
				var channel = factory.CreateChannel(GetRandomEndpoint());
				Label1.Text = channel.Say("Hola");
				
			}
			catch (Exception ex)
			{

				Label1.Text = ex.Message;
			}

			
		}
		private EndpointAddress GetRandomEndpoint()
		{
			var endpoints = RoleEnvironment.Roles["WcfWorker"].Instances.Select(i => i.InstanceEndpoints["InternalRest"].IPEndpoint).ToArray();
			var r = new Random(DateTime.Now.Millisecond);
			return new EndpointAddress(string.Format("net.tcp://{0}/InternalRest", endpoints[r.Next(endpoints.Count() - 1)]));
		}

Para esta parte es importante saber que servicio es el que esta expuesto para uso interno. Revisen CreateServiceHost();

Ahora publicamos y probamos.

image

Bueno, espero que sea de utilidad este post.

Sl2

Romny

Comunicación Interna – WCF en Azure

Hola a todos.

Muchas veces necesitamos hacer aplicaciones orientadas a servicios y además que estas se integren con otros sistemas de servicios como soa.

Para estos casos un simple rest no es factible debido a que se montara en Azure. Básicamente lo que se quiere es exponer un servicio wcf que ira por http pero la comunicación interna deberá ser por tcp por aquello de que tcp nos evita como dos capas del modelo osi.

Requerimientos

    Microsoft Azure SDK for .NET – 2.8.2

    Cuenta de Azure

    Creamos un proyecto Azure WorkerRole

    image

    image

    Después de creado el proyecto, damos en propiedades del role WcfWorker, vamos a extremos y añadimos los siguientes puntos.

    image

    Agregamos las siguientes referencias.

    image

    Agregamos una interface IService

    image

Agregamos una interface IWorker

image

Agregamos una clase Service que implemente las interfaces creadas.

image

Abrimos la clase WorkerRole.cs, creamos variables ServiceHost y añadimos el método CreateServiceHost para alojar su servicio WCF REST.

//Static channel factory for inter-role communication.
		private static ChannelFactory<IWorker> factory;

		//Service host varible.
		private ServiceHost serviceHost;


		private void CreateServiceHost()
		{
			//Url of service.
			Uri httpUri = new Uri(String.Format("http://{0}/{1}", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Rest"].IPEndpoint.ToString(), "Rest"));

			//Assign url to service host.
			serviceHost = new ServiceHost(typeof(Service), httpUri);

			//Adding endpoint for REST service.
			ServiceEndpoint ep = serviceHost.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");

			//Adding behavior for REST service.
			ep.Behaviors.Add(new WebHttpBehavior() { HelpEnabled = true });


			//NetTcpBinding with no security.
			NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);

			//Define an internal endpoint for inter-role traffic.
			RoleInstanceEndpoint internalEndPoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["InternalRest"];

			//Add internal endpoint.
			this.serviceHost.AddServiceEndpoint(typeof(IWorker), binding, String.Format("net.tcp://{0}/InternalRest", internalEndPoint.IPEndpoint));

			//Create channel factory for inter-role communication.
			WorkerRole.factory = new ChannelFactory<IWorker>(binding);

			//Open the service host  to start listening for messages.
			serviceHost.Open();

		}

Creamos el método NotifiyAllNodes para notificar en las instancias.

internal static void NotifyAllNodes(string message)
        {
            //Get the role id.
            string roleId = RoleEnvironment.CurrentRoleInstance.Id;


                //Gets a RoleInstance object representing the role instance in which this code is currently executing.
                var current = RoleEnvironment.CurrentRoleInstance;

                //Get all instances except the current.
                var endPoints = current.Role.Instances
                                .Where(instance => instance != current)
                                .Select(instance => instance.InstanceEndpoints["InternalRest"]);
                foreach (var ep in endPoints)
                {
                    //Internal endpoint address.
                    EndpointAddress address = new EndpointAddress(String.Format("net.tcp://{0}/InternalRest", ep.IPEndpoint));

                    //Channel for communication.
                    IWorker client = WorkerRole.factory.CreateChannel(address);

                    //Update all the instances.
                    client.UpdateMessage(message, ep.RoleInstance.Id);
                }
         }

Llamar método CreateServiceHost en método OnStart() .

Procedemos a publicar.

image

Cuando publicamos tenemos una exception.

HTTP could not register URL http://+:80/Rest/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details).

La solución a este problema es averiguar el puerto que necesita para abrir y dar permiso al rol de trabajo para abrir el puerto apropiado.

Para esto creamos un proyecto de consola.

image

Vinculamos el ejecutable al proyecto WorkerRole y seleccionamos que se copie siempre.

image

En el archivo de definición agregamos las siguientes líneas.

<Startup>
			<Task commandLine="PortDetect.exe" executionContext="elevated" taskType="simple">
			</Task>
		</Startup

Volvemos a publicar, Ahora se puede acceder al servicio rest que se aloja (en el puerto 80) en el WorkerRole y internamente se comunica por tcp.

Realizamos una prueba para ver que todo este bien.

image

Bueno, espero que sea de utilidad este post.

Sl2

Romny

Team Fundation Services – Crear Build

Hola a todos, seguimos con pequeños tips o ayudas a la hora de usar TFS. hoy vamos a crear un Build para nuestro proyecto. Esta labor se puede hacer desde Visual Studio o desde el Portal. Esta vez lo haremos desde el Portal.

Vamos al protal a la seccion de Build y damos agregar

image

se desplegara un formulario para escoger que tipo de solucion queremos hacer el build

image

en la siguiente escogemos nuestro repositorio, podemos usar aparte del sistema de repositorio de visual studio, podemos usar github,subversion, o cualquier sistema externo que utilice gitbug como bitbucket y damos crear.

image

Para este caso escogemos que se desea compilar una solución de visual studio y que limpie la solución y restaure paquetes cuando se ejecute. Ademas podemos configurar mas opciones, pueden revisar.

image

Lo ultimo es guardar y asignarle un nombre.

image

algo importante que deben saber es que la build o compilación se ejcutara automaticamente cuando subimos un cambio al repositorio de codigo.

image

Con esto ya pueden probar en sus implementaciones, espero les agrade y les sirva.

Sl2

Romny

Team Fundation Services–Politicas de Check-in

Hola a todos.

Dentro de mis nuevas actividades de trabajo esta el de administrar el Team Fundation Services de ahora en adelante TFS. Algo importante cuando trabajamos con TFS es crear politicas para hacer el trabajo de desarrollo mas facil.

La politica que creo es basica dentro de un esquema colaborativo es el de siempre pedir una descripción y de un elemeto relacionado de los Work Items al momento de hacer commit.

Para lograr esto en TFS es desde nuestro Visual Studio, nos conectamos el Team Project y vamos a la opcion de configuración.

image

Luego vamos a Control de codigo fuente

image

Luego vamos a Directiva de Protección y damos click en Agregar

image

Agregamos la Directiva de comentarios del conjunto de cambios y Elementos de trabajo.

image

Quedara de la siguiente forma.

image

Con esto ya quedan la politicas activadas, apenas intente subir cambios, las politicas se veran reflejadas.

image

Espero que este post les sirva.

Sl2

Romny

Parse, Terminado el Servicio.

Articulo Restablecido.

Hola a todos. Prosiguiendo con el blog, hoy quiero comentarles de un anuncio sobre Parse.

Este blog realizo dos breves post sobre Parse, un BaaS enfocado para aplicaciones moviles.

BaaS: Parse

Consumiendo Parse desde .NET

A mi parecer, me parecia un servicio bueno, tenia varios modulos enfocado para aplicaciones moviles, lo use en mi trabajo, y le tuve cierto aprecio. Muchos puritanos diran que como no tenia una empresa grande que los respaldara como otros productos en el mercado, ese era su destino, puede que si, pero no por eso le quitaremos que era una buena herramienta.

A todas las personas que lo usaban les llego un correo con la noticia, tambien la pueden leer en el portal, basicamente lo que dicen es el servicio estaba habilitado hasta enero 28 del 2017. Considero que es un buen tiempo para hacer las migraciones requeridas en los productos ya echos.

Tambien ofrecen una herramienta de migración y su servidor lo liberan bajo open source.

Asi que ha trabajar en sus respetivas migraciones.

 

Link del post:

Moving On

Sl2

Romny

Parse, Terminado el Servicio.

Hola a todos. Prosiguiendo con el blog, hoy quiero comentarles de un anuncio sobre Parse.

Este blog realizo dos breves post sobre Parse, un BaaS enfocado para aplicaciones moviles.

A mi parecer, me parecia un servicio bueno, tenia varios modulos enfocado para aplicaciones moviles, lo use en mi trabajo, y le tuve cierto aprecio. Muchos puritanos diran que como no tenia una empresa grande que los respaldara como otros productos en el mercado, ese era su destino, puede que si, pero no por eso le quitaremos que era una buena herramienta.

A todas las personas que lo usaban les llego un correo con la noticia, tambien la pueden leer en el portal, basicamente lo que dicen es el servicio estaba habilitado hasta enero 28 del 2017. Considero que es un buen tiempo para hacer las migraciones requeridas en los productos ya echos.

Tambien ofrecen una herramienta de migración y su servidor lo liberan bajo open source.

Asi que ha trabajar en sus respetivas migraciones.

 

Link del post:

Moving On

Sl2

Romny

Implementando Jquery DataTables en Asp.Net MVC 5 Part 2.

Hola a todo.

Continuando con nuestro anterior post. Implementando Jquery DataTables en Asp.Net MVC 5 Part 1. donde mostramos como usar la librería Jquery DataTables en nuestros proyectos de MVC. Pero el post se quedo corto dado que algunas funcionalidades no funcionan correctamente a la primera implementada, y este post cubre esas necesidades.

Partimos de nuestro código de inicio: https://github.com/romnyd/JqueyDataTables

Lo primero crearemos una clase en la carpeta Models, con el nombre “jQueryDataTableParams” la cual se encargara de manejar todos estos temas. “Búsqueda, filtro, orden”

image

Esta clase tendrá la siguiente estructura

   1: /// <summary>  

   2:    /// Class that encapsulates most common parameters sent by DataTables plugin  

   3:    /// </summary>  

   4:     public class jQueryDataTableParams

   5:     {

   6:         /// <summary>  

   7:         /// Request sequence number sent by DataTable,  

   8:         /// same value must be returned in response  

   9:         /// </summary>      

  10:         public string sEcho { get; set; }

  11:         /// <summary>  

  12:         /// Text used for filtering  

  13:         /// </summary>  

  14:         public string sSearch { get; set; }

  15:         /// <summary>  

  16:         /// Number of records that should be shown in table  

  17:         /// </summary>  

  18:         public int iDisplayLength { get; set; }

  19:         /// <summary>  

  20:         /// First record that should be shown(used for paging)  

  21:         /// </summary>  

  22:         public int iDisplayStart { get; set; }

  23:         /// <summary>  

  24:         /// Number of columns in table  

  25:         /// </summary>  

  26:         public int iColumns { get; set; }

  27:         /// <summary>  

  28:         /// Number of columns that are used in sorting  

  29:         /// </summary>  

  30:         public int iSortingCols { get; set; }

  31:         /// <summary>  

  32:         /// Comma separated list of column names  

  33:         /// </summary>  

  34:         public string sColumns { get; set; }

  35:  }

 

Para que la grilla funcione correctamente tendremos que crear una acción para que maneje todos estos temas por backend, en mi opinión es la mejor forma.

La estructura básica seria la siguiente.

   1: public ActionResult GetDataCustomers(jQueryDataTableParams param)

   2:         {

   3:  

   4:         }

Esta es la implementación final de esta acción, esta acción maneja todo los que necesita la grilla.

   1: public ActionResult GetDataCustomers(jQueryDataTableParams param)

   2:         {

   3:             //Traer registros

   4:             IQueryable<Customers> memberCol = db.Customers.AsQueryable();

   5:  

   6:             //Manejador de filtros

   7:             int totalCount = memberCol.Count();

   8:             IEnumerable<Customers> filteredMembers = memberCol;

   9:             if (!string.IsNullOrEmpty(param.sSearch))

  10:             {

  11:                 filteredMembers = memberCol

  12:                         .Where(m => m.CompanyName.Contains(param.sSearch) ||

  13:                            m.ContactName.Contains(param.sSearch) ||

  14:                            m.ContactTitle.Contains(param.sSearch) ||

  15:                            m.Address.Contains(param.sSearch) ||

  16:                            m.City.Contains(param.sSearch) ||

  17:                            m.Region.Contains(param.sSearch) ||

  18:                            m.PostalCode.Contains(param.sSearch) ||

  19:                            m.Country.Contains(param.sSearch) ||

  20:                            m.Phone.Contains(param.sSearch) ||

  21:                            m.Fax.Contains(param.sSearch));

  22:             }

  23:             //Manejador de orden

  24:             var sortIdx = Convert.ToInt32(Request["iSortCol_0"]);

  25:             Func<Customers, string> orderingFunction =

  26:                                 (

  27:                                 m => sortIdx == 0 ? m.CompanyName :

  28:                                   sortIdx == 1 ? m.ContactName :

  29:                                   sortIdx == 2 ? m.ContactTitle :

  30:                                   sortIdx == 3 ? m.Address :

  31:                                   sortIdx == 4 ? m.City :

  32:                                   sortIdx == 5 ? m.Region :

  33:                                   sortIdx == 6 ? m.PostalCode :

  34:                                   sortIdx == 7 ? m.Country :

  35:                                   sortIdx == 8 ? m.Phone :

  36:                                   sortIdx == 9 ? m.Fax :

  37:                                   m.CustomerID

  38:                                  );

  39:             var sortDirection = Request["sSortDir_0"]; // asc or desc  

  40:             if (sortDirection == "asc")

  41:                 filteredMembers = filteredMembers.OrderBy(orderingFunction);

  42:             else

  43:                 filteredMembers = filteredMembers.OrderByDescending(orderingFunction);

  44:             var displayedMembers = filteredMembers

  45:                      .Skip(param.iDisplayStart)

  46:                      .Take(param.iDisplayLength);

  47:  

  48:             //Manejardo de resultados

  49:             var result = from a in displayedMembers

  50:                          select new

  51:                          {

  52:                              a.CompanyName,

  53:                              a.ContactName,

  54:                              a.ContactTitle,

  55:                              a.Address,

  56:                              a.City,

  57:                              a.Region,

  58:                              a.PostalCode,

  59:                              a.Country,

  60:                              a.Phone,

  61:                              a.Fax

  62:  

  63:  

  64:                          };

  65:             //Se devuelven los resultados por json

  66:             return Json(new

  67:             {

  68:                 sEcho = param.sEcho,

  69:                 iTotalRecords = totalCount,

  70:                 iTotalDisplayRecords = filteredMembers.Count(),

  71:                 aaData = result

  72:             },

  73:                JsonRequestBehavior.AllowGet);

  74:         }

 

La vista cambia y solo devuelve la vista.

   1: public ActionResult Customers()

   2:         {

   3:             return View();

   4:         }

En la vista los cambios que hay que realizar son los siguientes.

  1. El foreach que cargaba los datos se elimina solo se deja la etiqueta <tbody> dado que toda esta información se cargara por backend.
  2. el jquery de carga cambia.
   1: <script type="text/javascript">

   2:         $(document).ready(function () {

   3:             $('#listar').dataTable({

   4:                 "bServerSide": true,

   5:                 "sAjaxSource": '@Url.Action("GetDataCustomers", "Home")',

   6:                 "bProcessing": true,

   7:                 "bdestroy": true,

   8:                 "start": 0,

   9:                 "order": [0, "asc"],

  10:                 "bDeferRender": true,

  11:  

  12:                 "aoColumns": [

  13:                         { "sName": "CompanyName", "mData": "CompanyName" },

  14:                         { "sName": "ContactName", "mData": "ContactName" },

  15:                         { "sName": "ContactTitle", "mData": "ContactTitle" },

  16:                         { "sName": "Address", "mData": "Address" },

  17:                         { "sName": "City", "mData": "City" },

  18:                         { "sName": "Region", "mData": "Region" },

  19:                         { "sName": "PostalCode", "mData": "PostalCode" },

  20:                         { "sName": "Country", "mData": "Country" },

  21:                         { "sName": "Phone", "mData": "Phone" },

  22:                         { "sName": "Fax", "mData": "Fax" },

  23:                         

  24:                 ],

  25:             });

  26:         });

Es importante leer la documentación dado que esta les indica que hacer para lo que desean implementar.

Ejecutamos y probamos.

image

image

Revisamos la consola del navegador y vemos que todo esta funcionando correctamente.

image

Espero que les haya gustado. S@ludos.

 

El código esta en esta url: https://github.com/romnyd/JqueyDataTables

 

Romny

Implementando Jquery DataTables en Asp.Net MVC 5 Part 1.

Hola a todos.

Hoy quiero mostrarles como implementar el plugin DataTables para Jquery en una solución de Asp.Net MVC 5.

DataTables es un plugin para la librería de Jquery, el cual nos permite crear una grilla muy potente, esta grilla tiene funcionalidades de búsqueda, filtrado, paginación, exportación entre otras. Para revisar mas ir a al sitio el cual contiene cantidad de información para hacer sus implementaciones.

Lo primero para empezar es crear nuestro proyecto.

image

image

Después de crear nuestro proyecto vamos al administrador de paquetes de nuget.

image

Buscamos “datables” y damos instalar.

image

El sistema procede a instalar.

image

Verificamos la instalación.

image

Procedemos a configurar el respectivo bundle para el javascript y configurar el css.

   1: bundles.Add(new ScriptBundle("~/bundles/datatables").Include(

   2:                 "~/Scripts/DataTables/jquery.dataTables.js", "~/Scripts/DataTables/dataTables.tableTools.js",

   3:                 "~/Scripts/DataTables/dataTables.scroller.min.js",

   4:                 "~/Scripts/DataTables/dataTables.bootstrap.js"

   5:                 ));

 

   1: bundles.Add(new StyleBundle("~/Content/css").Include(

   2:                       "~/Content/bootstrap.css",

   3:                       "~/Content/site.css",

   4:                       "~/Content/DataTables/css/dataTables.bootstrap.css"));

 

Para la conexión a datos usaremos la bd de NORTHWND y crearemos un modelo DataBaseFirts de EntityFramework.

image

image

image

image

Después de tener nuestro modelo, procedemos a crear nuestra vista que implementara DataTables. La forma basica de implementar DataTables es crear nuestro conjunto de datos, pasarlos a la vista y en la vista instanciar la librería.

   1: public ActionResult Customers()

   2:         {

   3:             var customers = db.Customers.ToList();

   4:             return View(customers);

   5:         }

Creamos la vista con el scaffolding y configuramos la librería.

   1: @section scripts

   2: {

   3:     @Scripts.Render("~/bundles/jquery")

   4:     @Scripts.Render("~/bundles/datatables")

   5:     <script type="text/javascript">

   6:         $(document).ready(function () {

   7:             $('#listar').DataTable({

   8:                 "paging": true,

   9:                 "recordsFiltered": 10,

  10:                 "lengthChange": false,

  11:                 "searching": true,

  12:                 "ordering": true,

  13:                 "info": true,

  14:                 "autoWidth": false

  15:             });

  16:         });

  17:     </script>

  18: }

Ejecutamos y vemos como se comporta la libreria.

image

En un principio esta todo bien pero hay un error de javascript, esto error ocurre por que la tabla no esta definida correctamente.

Faltan los <thead> y los <tbody>, corregimos esto y volvemos a probar.

image

En este punto tenemos funcionando la librería, pero esta a medias, por que si nos fijamos el paginado no esta funcionando, el filtro y ordenamiento tampoco

image

Estas funcionalidades las revisaremos en nuestro siguiente post.

El código esta en esta url: https://github.com/romnyd/JqueyDataTables

Espero que les haya gustado. S@ludos.

Romny

React.js en Asp.Net MVC

Hola a todos, hoy quiero hablar de un librería de JavaScript que va a revolucionar el mundo del desarrollo web.

Que es React.js?

React.js es una librería open source de JavaScript, patrocina por facebook y no solo eso, también la utiliza en sus productos. Esta librería esta basada en componentes, la idea es poder reutilizar todos los componentes que se utilizan en el desarrollo web, como botones, barras, etc., también una de sus fortalezas es que mantiene el contenido actualizado en todo momento. React,js utiliza archivos JSX que es un nuevo tipo de archivo que mesclar JavaScript con HTML, también permite compartir código de forma nativa para android y iPhone.

 

Para mas informacion en: https://facebook.github.io/react/

Usando React.js con Asp.Net MVC

Lo primero es crear un proyecto nuevo.

image

image

Procedemos a instalar React.js desde el administrador de paquetes.

image

image

Procedemos a crear una vista básica.

image

 

 

1 @{ 2 Layout = null; 3 } 4 <html> 5 <head> 6 <title>Hello React</title> 7 </head> 8 <body> 9 <div id="content"></div> 10 <script src="http://fb.me/react-0.13.1.js"></script> 11 <script src="@Url.Content("~/Scripts/Tutorial.jsx")"></script> 12 </body> 13 </html>

 

Procedemos a crear nuestro archivos jsx

image

1 var CommentBox = React.createClass({ 2 render: function() { 3 return ( 4 <div className="commentBox"> 5 Hello, world! I am a CommentBox. 6 </div> 7 ); 8 } 9 }); 10 React.render( 11 <CommentBox />, 12 document.getElementById('content') 13 );

Ejecutamos y deberíamos ver algo así.

 

image

El mismo ejemplo anterior lo podemos cambiar a la convension de ReactJS

1 var CommentBox = React.createClass({displayName: 'CommentBox', 2 render: function() { 3 return ( 4 React.createElement('div', {className: "commentBox"}, 5 "Hello, world! I am a CommentBox." 6 ) 7 ); 8 } 9 }); 10 React.render( 11 React.createElement(CommentBox, null), 12 document.getElementById('content') 13 );

 

Hasta este momento, no hemos explotado lo que es ReactJS, en nuestro próximo post, adentraremos en el uso de esta librería.

 

Sl2

Romny

Consumiendo Parse desde .NET

Hola a todos.

Prosiguiendo con el tema de Parse, en el cual en la entrada anterior vimos un poco lo que es este BaaS y algunas generalidades.

Para mas información: http://geeks.ms/blogs/rduarte/archive/2015/02/11/baas-parse.aspx

 

En esta entrada vamos a demostrar como seria consumir nuestra App creada en Parse desde .NET

Crear App MVC

Lo primero será crear un aplicación MVC

image

image

Componentes

Para poder conectarse con Parse debemos instalar el siguiente Nuget que nos proveerá lo necesario.

image

Trabajar con Parse

Después de tener lo necesario para trabajar con Parse, necesitamos la key de identificación, para eso vamos al portal y obtenemos dichas key.

image

En la aplicación en el Global.asax, inicializamos el cliente con Parse, para esto necesitamos las key de Application ID y NET Key.

image

Para este ejemplo me cree una clase books la cual se muestra así.

image

A modo de ejemplo realizare el código lo mas fácil, para no complicarnos.

image

Después de ejecutar el código, revisamos en Parse y se muestra el registro que acabamos de insertar.

image

De esta forma podemos consumir Parse de una forma sencilla y fácil. En próximos post trataremos de afrontar otros temas con Parse.

 

Espero que les haya gustado.

 

Sl2

Romny