martes, 22 de noviembre de 2016

Hosting Windows, ASP.NET y SQL Server

Hoy les hablaré un poco sobre mi proyecto de Servidores de Hosting y que me motivó a emprender en este segmento.

Como programadores en estas tecnologías (si bien tenemos Azure) nos cuesta un poco de trabajo encontrar un hosting ya sea gratuito o barato para poder desplegar nuestros proyectos. El abuso con el que algunas empresas inflan los precios, revendedores que tardan tiempo en dar una respuesta a una incidencia me motivaron a ir emprendiendo en este nuevo segmento.

Inicié con un propio servidor rentado en la infraestructura de Softlayers. Al principio solo pensaba utilizarlo para mis proyectos personales y una que otra página web de amigos, pero después de recordar el martirio que es encontrar un hosting flexible decidí emprender para ofrecer mis servicios a estudiantes o programadores que aún no cuentan con el capital suficiente para poder pagar un hosting dedicado.

Así que se interesa :) puedes visitar mi página web: https://www.adagioti.com/Servicios/ConsultoriaTI
O directamente la tienda: https://ventas.adagioti.com/cart.php?gid=3

Para conocer más sobre los servicios que te ofrezco. 

lunes, 21 de noviembre de 2016

Crear una conexion MySQL + NetCore (Ejemplo CRUD)


En esta entrada aprenderemos a crear una conexión entre MySQL y NetCore utilizando EntityFramework. 

Primer paso, abrimos una consola de comandos [ en mi caso CMD / Windows 10 ] y crearemos la estructura de la aplicación utilizando Yeoman 

En el interprete de comando escribimos la siguiente instrucción: 

yo aspnet 

Como nombre le pondré mysqltest para hacer referencia a que estaremos trabajando en hacer una prueba de conexión a MySQL 

Abrimos el folder de la aplicación con Visual Studio Code 


Buscamos el archivo Project.json y agregaremos las siguientes líneas de código: 

En el apartado Dependencias (Dependencies): 

"Microsoft.EntityFrameworkCore.InMemory": "1.0.1",    "Microsoft.EntityFrameworkCore": "1.0.1",    "MySql.Data.EntityFrameworkCore": "7.0.6-IR31",    "Microsoft.EntityFrameworkCore.Tools": { 
     "version": "1.0.0-preview2-final", 
     "type": "build"
    }
En el apartado tools agregaremos las siguientes líneas:
"Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview2-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    } 

Después de realizar esta modificación, VSC nos preguntará que si deseamos restaurar las dependencias, eliges la opción Restore y esperamos a que las dependencias sean restauradas. El tiempo de restauración dependerá en gran medida de tu conexión a Internet.

Ahora abrimos el archivo appsettings.json y agregamos la siguiente cadena de conexión:

,
  "ConnectionStrings": {
    "DefaultConnection": "server=localhost;userid=tuusuario;pwd=tupassword;port=3306;database=mysqltest;sslmode=none;"
  },
  "Data": {
    "AuroraConnection": {
      "InMemoryProvider": false
    }
  }
Donde los apartados tuusuario y tupassword equivalen a tu usuario y contraseña local.

Ahora, procederemos a crear una carpeta con el nombre Entities y otra con el nombre Infraestructura.

Creamos una nueva entidad de nombre Persona dentro de la carpeta Entities

namespace mysqltest.Entities
{
    public class Persona {
        public int Id {get;set;}
        public string Nombre {get;set;}
        public string Telefon {get;set;}
        public string Direccion {get;set;}
    }
}

Ahora, dentro de la carpeta Infraestructure crearé una clase llamada MySqlContexto.cs que contendrá el contexto de la aplicación.

using Microsoft.EntityFrameworkCore;
using mysqltest.Entities;
namespace mysqltest.Infraestructura
{
    public class MySqlContexto: DbContext
    {
        public MySqlContexto(DbContextOptions<MySqlContexto> options )
        :base (options){}
        //Databaseset
        public DbSet<Persona> Personas {get;set;}
    }

Ahora nos dirigimos al archivo Startup.cs y agregamos la siguiente línea de código


        public void ConfigureServices(IServiceCollection services)
        {
             string sqlConnectionString = Configuration["ConnectionStrings:DefaultConnection"];
            bool useInMemoryProvider = bool.Parse(Configuration["Data:AuroraConnection:InMemoryProvider"]);

            // Add framework services.
            services.AddDbContext<MySqlContexto>(options =>
            {
                switch (useInMemoryProvider)
                {
                    case true:
                        options.UseInMemoryDatabase();
                        break;
                    default:
                        options.UseMySQL(sqlConnectionString);
                        break;
                }
            });
            // Add framework services.
            services.AddMvc();
        }

Ahora abrimos el Terminal CTRL + ñ y ejecutaremos las siguientes instrucciones:

dotnet ef migrations add inicial

ahora ejecuta

dotnet ef database update

Este ultimo comando nos creará la estructura de la base de datos a partir de la entidad



Ahora le daremos funcionalidad a la aplicación, vamos a crear un controlador llamado PersonasController dentro de la carpeta Controller

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using mysqltest.Entities;
using mysqltest.Infraestructura;
namespace mysqltest.Controllers
{
    public class PersonasController : Controller
    {
        private readonly MySqlContexto _contexto;
        public PersonasController(MySqlContexto contexto)
        {
            _contexto = contexto;
        }
        //Retorna la información contenida en la base de datos
        public async Task<IActionResult> Index(){
            return View(await _contexto.Personas.ToListAsync());
        }
        //Detalles de la persona
        public async Task<IActionResult> Detalles(int id){
            if(id==null)
            {
                return NotFound();
            }
            var persona = await _contexto.Personas.SingleAsync(p=>p.Id == id);
            if(persona==null)
            {
                return NotFound();
            }
            return View(persona);
        }
      public IActionResult Create()
      {
          return View();
      }
      [HttpPost]
      [ValidateAntiForgeryTokenAttribute]
        public async Task<IActionResult> Create (Persona p)
        {
            if(ModelState.IsValid)
            {
                _contexto.Personas.Add(p);
                await _contexto.SaveChangesAsync();
                return RedirectToAction("Index");
            }
            return View(p);
        }
        public  async Task<IActionResult> Editar(int Id)
      {
          if(Id == null)
          {
              return NotFound();
          }
          var p = await _contexto.Personas.SingleOrDefaultAsync(per => per.Id== Id);
          if(p== null)
          {
              return NotFound();
          }
          return View(p);
      }
      [HttpPost]
      [ValidateAntiForgeryTokenAttribute]
        public async Task<IActionResult> Editar (Persona p)
        {
         
          if(p.Id == 0)
          {
              return NotFound();
          }
          if(ModelState.IsValid){
              try{
                  _contexto.Update(p);
                  await _contexto.SaveChangesAsync();
              }catch(DbUpdateConcurrencyException)
              {
                  return RedirectToAction("Index");
              }
                  return RedirectToAction("Index");
          }
            return View(p);
        }
        public async Task<IActionResult> Borrar(int id)
        {
            if(id==null)
            {
                return NotFound();
            }
            var persona = await _contexto.Personas.SingleOrDefaultAsync(per => per.Id == id);
            if(persona == null)
            {
                return NotFound();
            }
            return View(persona);
        }
        [HttpPost, ActionName("Borrar")]
        [ValidateAntiForgeryTokenAttribute]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            var p = await _contexto.Personas.SingleOrDefaultAsync(per => per.Id == id);
            _contexto.Personas.Remove(p);
            await _contexto.SaveChangesAsync();
            return RedirectToAction("Index");  
        }
    }
}

Dentro de la carpeta Views crearemos un nuevo folder al que le pondremos por nombre Personas, dentro de la carpeta Personas creamos los siguiente archivos:

Index.cshtml,

@model IEnumerable<mysqltest.Entities.Persona>
@{
    ViewData["Title"] = "Inicio Personas";
}
<h2>Index</h2>
<p>
    <a asp-action="Create">Nuevo Registro</a>
</p>
<table class="table">
        <thead>
            <tr>
                <th>Nombre</th>
                <th>Dirección</th>
                <th>Teléfono</th>
                <th></th>
                </tr>
        </thead>
        <tbody>
            @foreach(var item in Model)
            {
                <tr>
                    <td>@Html.DisplayFor(modelItem=> item.Nombre)</td>
                    <td>@Html.DisplayFor(modelItem=> item.Direccion)</td>
                    <td>@Html.DisplayFor(modelItem=> item.Telefon)</td>
                    <td> <a asp-action="Editar" asp-route-id="@item.Id"> Editar</a> |<a asp-action="Borrar" asp-route-id="@item.Id"> Borrar</a></td>
                 </tr>
            }
        </tbody>
</table>

Create.cshtml,

@model mysqltest.Entities.Persona
@{
    ViewData["Title"] = "Crear un nuveo registro de Personas";
}
<h2>Nuevo registro</h2>
 @using (Html.BeginForm())
        {
           
                    @Html.AntiForgeryToken()
                    @Html.ValidationSummary(true)
                    <div class="form-horizontal">
                        <label class="col-sm-2 control-label">Nombre:</label>
                        <div class="col-sm-4">
                            @Html.TextBoxFor(model=>model.Nombre)
                        </div>
                    </div>
                    <div class="form-horizontal">
                        <label class="col-sm-2 control-label">Direccion</label>
                        <div class="col-sm-4">
                            @Html.TextAreaFor(model =>model.Direccion)
                        </div>
                    </div>
                    <div class="form-horizontal">
                        <label class="col-sm-2 control-label">Telefono</label>
                        <div class="col-sm-4">
                            @Html.TextBoxFor(model=>model.Telefon)
                        </div>
                    </div>
                   
                        <button type="submit" class="btn btn-success btn-rounded">Guardar</button>
        }

Borrar.cshtml
@model mysqltest.Entities.Persona
@{
    ViewData["Title"] = "Eliminar registro de Personas";
}
<div class="alert alert-danger fade in">
    <h4>Aurora confirmaciones</h4>
    <p>¿Estás completamente que quieres eliminar el siguiente elemento: @Html.DisplayFor(model => model.Nombre) del sistema? </p>
    <p>
        @using (Html.BeginForm())
        {
            @Html.AntiForgeryToken()
            <div class="form-actions no-color">
                <div class="btn-group-list pull-right">
                    <input type="submit" value="Eliminar" class="btn btn-rounded btn-danger " />
                </div>
            </div>
        }
    </p>
</div>



Descarga el código fuente desde mi repositorio Git Hub Descargar






domingo, 20 de noviembre de 2016

Preparando el proyecto del Servicio Nacional del Empleo Unidad Lázaro Cárdenas.

Esta vez tengo la oportunidad de realizar un sistema para mejorar el servicio que brinda la oficina del Servicio Nacional del Empleo Unidad Lázaro Cárdenas.

El proyecto surge de una necesidad para automatizar la forma en la que se general los reportes, centralizar la información, acelerar el tiempo de atención del personal que va a consultar vacantes, así como también de las empresas que ofrecen una vacante.

Para este proyecto pretendo utilizar las siguientes Tecnologías.

Para el desarrollo

  1. Microsoft NETCORE en su versión 1.0 
  2. MySQL 5.5 (MariaDB) 
  3. Visual Studio Code. 
  4. Angular2 + TypeScript 
  5. Windows 10. 
Despliegue 
  1. Linux Ubuntu 16.04 64bits Virtualización VMWare. 
De aquí en adelante iré narrando todo el proceso de desarrollo de la Aplicación. 

1. Abriré una terminal y escribiré el siguiente comando yo aspnet asumiendo que tienes instalado Yeoman con Aspnetcore instalado. 



En la ventana de opciones elegiré Web Application Basic [ Without Membership And Authorization]

A continuación me pregunta con que framework web quiero trabajar, para el proyecto trabajaré con BootStrap 3.3.6

Posteriormente preguntará que nombre le queremos poner, en mi caso le pondre snelazaro



A continuación damos Enter para que nos cree la estructura del proyecto, a continuación obtendremos la estructura básica del proyecto.


Lo que ahora toca realizar es dotnet restore para restaurar las dependencias y dotnet run para poder ver el funcionamiento de la estructura en el navegador. 

Pero antes de ejecutar estos comandos incluiremos las siguientes dependencias con las que vamos a trabajar en todo el desarrollo de la aplicación. 

Estas entradas deberemos de incluirlas en nuestro archivo project.json apartado dependencies.
"Microsoft.AspNetCore.Identity": "1.0.0",
"Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.1",
"Microsoft.EntityFrameworkCore.InMemory": "1.0.1",
"Microsoft.EntityFrameworkCore": "1.0.1",
"MySql.Data.Core": "7.0.4-IR-191",
     "MySql.Data.EntityFrameworkCore": "7.0.4-IR-191",
     "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview2-final",
      "type": "build"
    },
A continuación guardamos y ejecutamos el comando dotnet restore, con esto restauraremos todas las dependencias con las que queremos trabajar.

A continuación ejecutamos el comando dotnet run para comprobar que la aplicación fue creada con éxito, para ello escribimos en el navegador: http://localhost:5000 y nos deberá de presentar la pantalla de bienvenida a ASPNET CORE


En las siguientes entradas iremos diseñando la funcionalidad de la aplicación.