[Article] .Net Core | User Secrets

En tiempo de desarrollo .Net Core nos brinda esta excelente funcionalidad la cual nos permite guardar configuraciones en nuestro perfil de usuario loca de una forma segura y sencilla. Estás funcionalidad nos ayuda a no subir por error o a no modificar los archivos con información privada en servidores o inclusive en nuestros sistemas de control de código fuente como GitHub, Bitbucket o Team Foundation Service.

Objetivo

En esta entrega estaremos viendo qué es, cómo configurar y utilizar User Secrets. .

Audiencia

Este documento está dirigido a personas que conocen muy poco o nada sobre el tema o personas que desarrollan tareas de consultoría de desarrollo o que simplemente están interesados en leer e investigar sobre la tecnología alcanzada por esta publicación.

Desarrollo

Antiguamente, en nuestras aplicaciones .Net, teníamos la posibilidad de encriptar nuestra información secreta contenida en los archivos web.config. Lo cual a veces lo hacía un poco incómodo al tener que implementar las aplicaciones o guardarlas en nuestros repositorios de código ya que se guardaban información sensible.

Ahora podemos guardar información sensible de la mano User Secrets de forma segura. Entre las cosas que podemos guardar tenemos: cadenas de conexión, claves de API, datos del cliente, datos de cualquier red social o de cualquier aplicación. Todo lo que nosotros consideremos como datos sensible puede ser almacenado sin correr riesgos de exponerla públicamente.

En mi caso me es muy útil cuando subo ejemplos a GitHub. Lo utilizo para subir un ejemplo sin la necesidad de tener que subir en el ejemplo los datos de acceso aun APi que utilizo en Azure o de alguna red social.

Microsoft.Extensions.SecretManager.Tools

Para poder utilizar y tener disponible esta funcionalidad deberemos usar Microsoft.Extensions.SecretManager.Tools.  Secret Manager almacena la información fuera del proyecto y nos permite no solo usar en el proyecto actual, también, nos brinda la posibilidad de usarlo en varios proyectos.

Lo instalaremos desde la consola de los paquetes Nuget en nuestra aplicación.

Una vez instalado hacemos botón derecho sobre nuestro proyecto y seleccionaremos del menú la opción “Manage User Secrets”:

Nos abrirá un archivo del tipo JSON llamado secrets.json. Este archivo guardaran los datos que necesitemos. Este se crea automáticamente y se ubica dentro de una carpeta protegida del sistema. podremos encontrarlo por medio de una estructura  de carpeta similar a esta:

%APPDATA%\Microsoft\UserSecrets\user-secrets-id\secrets.json

Si queremos ver el User-Secrets-Id podemos ubicarlo haciendo click derecho sobre el proyecto y seleccionado la opción “Edit <Nombre del proyecto>.csproj”. Este nos mostrar el archivo de configuración del proyecto con el id dentro:

En nuestro archivo JSON agregaremos un valor con motivo de poder tener información para poder ser consumida más adelante:

{
"TopSecret": "TopSecretValuePasssUserRoot"
}

El siguiente paso es configurarlo en nuestra aplicación Web el servicio. Abriremos el archivo Startup.cs y modificaremos el constructor para que lo tengamos disponible con las siguientes líneas:

Hasta ahora ya tenemos activo nuestro servicio de UserSecrets, agregamos un valor en nuestro archivo secrets.json y configuramos en el constructor para poder acceder. Ahora vamos a consumir el valor desde nuestro archivo. Iremos al HomeController.cs e inyectamos en constructor IConfiguration para tener disponible la consulta del valor:

Por último, Lo ejecutaremos y comprobaremos si está recuperando el error correctamente:

Conclusión

En este post hemos visto  que es, como configurarlo y cómo utilizar UserSecrets. El uso de esta funcionalidad no brinda una gran posibilidad de no estar obligados o por error a subir información confidencial de nuestras cuentas de redes sociales, conexión a base de datos o cualquier información sensible que consideremos.

[Tutorial] Javascript | TypeScript – Parte 8

En esta octava entrega continuaremos con nuestro demo de TypeScript junto a Jquery. Recordemos que utilizaremos un proyecto que hicimos en otro post: “Crear una App en Asp.Net Core en Linux”. En nuestro post anterior habíamos dejado todo listo para comenzar nuestra aplicación.

Objetivo

En esta octava entrega continuaremos con nuestro demo de TypeScript junto a Jquery. Recordemos que utilizaremos un proyecto que hicimos en otro post: “Crear una App en Asp.Net Core en Linux”. En nuestro post anterior habíamos dejado todo listo para comenzar nuestra aplicación.

Audiencia

Este documento está dirigido a personas que conocen muy poco o nada sobre el tema o personas que desarrollan tareas de consultoría de desarrollo o que simplemente están interesados en leer e investigar sobre la tecnología alcanzada por esta publicación.

Desarrollo

Nuestra aplicación tendrá unas funcionalidades bastantes simples. Sera un ABM de clientes los cuales consumen servicios rest para almacenar y actualizar la información. No voy a entrar en detalle de la interfaz gráfica. Usaremos AdminLTE que está basada en Bootstrap como interfaz gráfica. Les dejare el demo completo en github para que puedan consultarlo cuando lo necesiten.

Crearemos un carpeta que se llame customers. Dentro tendremos la página web inicio de nuestro ABM que se llamara customer-index.html.

Crearemos otra carpeta llamada src donde tendremos el archivo app.ts que creamos en el post anterior. Agregaremos: customers.ts, customerTypes.ts y GenericRepository.ts.

En nuestro archivo customer-index.html deberemos agregar una línea que código la cual ara referencia a bundle creado por webpack y que es el que realmente ejecutará nuestra aplicación.

&lt;script src="/dist/app.js"&gt;&lt;/script&gt;

Empezaremos por nuestro archivo GenericRepository.ts. Este archivo contendrá un interface junto a un clase repositorio. Esta clase repositorio la utilizaremos como clase genérica para cualquier acceso a datos que necesitemos. Veamos el código:

import * as $ from 'jquery'

export interface IRepository&lt;T&gt;{
GetAll(): JQueryPromise&lt; Array&lt;T&gt; &gt;;
GetById(id: number): JQueryPromise&lt;T&gt;;
Delete(id: number) : JQueryPromise&lt;void&gt;;
Save(entity: T) : JQueryPromise&lt;T&gt;;
Update(id:number, entity: T) : JQueryPromise&lt;void&gt;;
}

export class Repository&lt;T&gt; implements IRepository&lt;T&gt;{

constructor(public serviceUrl: string){}

getServiceUrl():string {
return this.serviceUrl;
}

GetById(id: number): JQueryPromise&lt;T&gt; {
return &lt;JQueryPromise&lt;T&gt;&gt;$.ajax({
type: "GET",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
url: this.serviceUrl + "/" + id
});
}
GetAll(): JQueryPromise&lt; Array&lt;T&gt; &gt; {
$.support.cors=true;
return &lt;JQueryPromise&lt;Array&lt;T&gt;&gt;&gt;$.ajax({
type: 'GET',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
url: this.serviceUrl
});
}

Delete(id: number): JQueryPromise&lt;void&gt; {
return &lt;JQueryPromise&lt;void&gt;&gt;$.ajax({
type: "DELETE",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
url: this.serviceUrl + "/" + id
});
}
Save(entity: T): JQueryPromise&lt;T&gt;{

return &lt;JQueryPromise&lt;T&gt;&gt;$.ajax({
type: "POST",
url: this.serviceUrl,
data: JSON.stringify(entity),
contentType: "application/json; charset=utf-8",
dataType: 'json'
});
}

Update(id:number, entity: T): JQueryPromise&lt;void&gt; {
return &lt;JQueryPromise&lt;void&gt;&gt;$.ajax({
type: "PUT",
url: this.serviceUrl + "/" + id ,
data: JSON.stringify(entity),
contentType: "application/json; charset=utf-8",
dataType: 'json'
});
}
};

La primera línea que podemos ver es muy importante. Esta línea hace que podamos importar y tener disponible JQuery. Automáticamente como instalamos el archivo de tipos específicos para JQuery tendremos intellisense disponible:

La segunda línea también muy importante importara nuestra clase base repository para que podamos extenderlas en nuestras clases de negocio.

En nuestra interface Repository declaramos los métodos básicos y necesarios de cualquier Repositorio con una base de tipos de Datos genéricos que podemos ver representado por <T>. Este contrato obligará a las clases que lo implementen tengan estos métodos.

Más adelante, en el mismo archivo, podemos ver la implementación de nuestra interface en una clase también genérica llamada Repository. Esta clase implementa los métodos y la funcionalidad de nuestro repositorio. Veamos el método GetByID.

En este método o como el de los demás podemos ver que el método devolverá un JQueryPromise genérico como también que está usando el método de Jquery $.ajax. El cual es encargado de invocar los servicios Rest.

Dentro de nuestro archivo customer.ts implementaremos nuestra clase RepositoryCustomers la cual extenderá Repository<T>. Aqui esta la clase completa

import * as $ from 'jquery'
import { Repository } from './GenericRepository'

export class ModelCustomer {
customerId: number;
firstName: string;
middleName: string;
surName: string;
emailAddress: string;
customerTypeId: number;
notes: string;
}

export class ModelPageCustomer {
countPages: number;
countCustomers: number;
actualPage : number;
customers : Array&lt;ModelCustomer&gt;;
}

export class RepositoryCustomers extends Repository&lt;ModelCustomer&gt;{

constructor(){
super("http://localhost:8044/api/customers");
}

GetPage(page: number): JQueryPromise&lt; ModelPageCustomer &gt; {

return &lt;JQueryPromise&lt;ModelPageCustomer&gt;&gt;$.ajax({
type: "GET",
contentType: 'application/json; charset=utf-8',
url: super.getServiceUrl() + "/" + page + "/30"
});
}
}

Podemos ver en nuestra archivo 2 clases mas: ModelCustomer y ModelPageCustomer. La primera es un modelo para nuestros datos de clientes y la segunda es un modelo para paginar en nuestra vista de listado.

En el archivo customerTypes.ts tendremos una implementación similar, pero, para los tipos de nuestros clientes. La clase RepositoryCustomersTypes igualmente que nuestra clase anterior extenderá Repository<T> pero para el modelo ModelCustomerType.

Por último veamos nuestro archivo app.ts. En este archivo tendremos la implementación de las funcionalidades de nuestra interfaz gráfica. Está funcionalidades consumen nuestros repositorios. Lo más importantes son las 3 primeras líneas.


import { RepositoryCustomers, ModelCustomer, ModelPageCustomer } from './customers';
import { RepositoryCustomersTypes, ModelCustomerType } from './customersTypes';
import * as $ from 'jquery';

En estas líneas importamos todo lo necesario para nuestra vista y sus funcionalidades.

Conclusión

En este post hemos visto un acercamiento al demo hecho en javascript. Pueden descargar el proyecto desde la dirección de github https://github.com/withoutdebugger/DemoTypeScript. En el próximos post tocaremos algunos temas más complejos de que podemos desarrollar con TypeScript.

[Tutorial] Javascript | TypeScript – Parte 7

En esta séptima entrega veremos un ejemplo del uso de TypeScript junto a Jquery. Utilizaremos un proyecto que hicimos en otro post: “Crear una App en Asp.Net Core en Linux”. Estos servicios lo usaremos de repositorio de información.

Objetivo

En esta séptima entrega veremos un ejemplo del uso de TypeScript junto a Jquery. Utilizaremos un proyecto que hicimos en otro post: “Crear una App en Asp.Net Core en Linux”. Estos servicios lo usaremos de repositorio de información.

Audiencia

Este documento está dirigido a personas que conocen muy poco o nada sobre el tema o personas que desarrollan tareas de consultoría de desarrollo o que simplemente están interesados en leer e investigar sobre la tecnología alcanzada por esta publicación.

Desarrollo

Para comenzar vamos a configurar nuestra aplicación con todo lo que necesitamos para el demo. Primero creamos una carpeta, en mi caso la nombraré DemoTypeScript, pero pueden ponerle el nombre que deseen. Luego abriremos la carpeta con visual code.

Una vez abierto ejecutaremos en la consola de VS Code el primero comentado que inicializará el archivo necesario para npm.

npm init

El siguiente comando que ejecutaremos instalará TypeScript y ts-loader. El ts-loader lo usaremos junto a webpack que será instalado más adelante.

npm install --save-dev typescript ts-loader

Le toca a Jquery.

npm install --save-dev jquery

Antes de seguir con los comandos vamos a tocar un tema que habíamos dejamos pendiente y es “Typings”. En nuestro ejemplo queremos usar JQuery, pero tenemos un problema, este no fue hecho con TypeScript. Entonces ¿Cómo podemos tener soportes de tipos usando esta librería?.

Para esto existen Type Script Definitions Files. Estos archivos con la extensión d.ts describen los métodos, tipos y objetos de las librerías que no fueron hechas con TypeScript brindándonos el soporte de tipos. Estos archivos los utilizará el compilador para validar tipos y en el caso los programas, como VS Code, la intellisense en tiempo de desarrollo.

Veamos los pasos para instalar Typings. Debemos instalarlo en nuestro proyecto por medio de comandos npm.

npm install --save-dev typings

Una vez que tenemos instalado el soporte de typings debemos descargar e instalar el soporte para jquery de la siguiente forma:

typings install dt~jquery --global --save

Esto nos creara en nuestro proyecto una carpeta llamada typing que en su interior tendrá los archivos necesarios.

Lo siguiente en la lista es instalar es Webpack. Webpack es una herramienta que nos ayudará a transpilar nuestro codigo TypeScript de una manera más sencilla. Posee muchísimas funciones, pero por este momento, solo utilizaremos la capacidad de generar bundles a partir de nuestro código. Lo instalaremos con el siguiente comando npm:

npm install --save-dev webpack

Empecemos con las configuraciones. Primero creamos el archivo config.json con el siguiente comando:

tsc -init

Lo siguiente es crear una carpeta que llamaremos src que contendrá nuestro código y dentro un archivo que se llamará app.ts el cual será el inicio de nuestra aplicación. Para que TypeScript reconozcas los tipos configurado en el archivo d.ts correspondiente a JQuery debemos agregar las siguientes líneas:

"files": [
"typings/index.d.ts",
"src/app.ts"
]

El archivo index.d.ts le indicara de donde debe tomar los tipos y app.ts le dirá dónde debe iniciar nuestra aplicación. Nuestro archivo tsconfig.json quedara algo asi:

{
"compilerOptions": {
"target": "es5",
"sourceMap": true,
"outDir": "./dist",
"strict": true
}
,
"files": [
"typings/index.d.ts",
"src/app.ts"

]
}

Nos queda solo agregar el archivo de configuración para Webpack. Crearemos un archivo webpack.config.js y le agregaremos el siguiente contenido:


var path = require('path');
var webpack = require('webpack');

module.exports = {

devtool: 'source-map',
entry: ['./src/app.ts'],
output:{
path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
},
module:{
loaders:[
{
test: /\.ts$/,
include: path.resolve(__dirname, 'src'),
loader: 'ts-loader'
}]
},
resolve:{
extensions: [".webpack.js",".web.js", ".ts", ".js"]
}
};

Para comprobar que todo funciona correctamente completaremos nuestro archivo app.ts que se encuentra en la carpeta src con el siguiente código:

class Main{
mySite:string = "http://www.withoutdebugger.com";
}

Iremos a nuestra consola y ejecutaremos el siguiente comando:

node_modules\.bin\webpack

Ahora podemos ver una nueva carpeta con el archivo final de nuestra aplicación.

Por último instalaremos un servidor web liviano hecho en nodejs.

npm install http-server

Y podemos invocarlos desde la consola de VSCode simplemente con el comando:

http-server

Conclusión

En este post hemos configurado todo lo necesario para comenzar nuestra aplicación demo. En el próximo post entramos ya en nuestra aplicación demo.

[Tutorial] Javascript | TypeScript – Parte 6

En esta sexto post tocaremos los temas: namespaces, módulos y decoradores, como se usan en TypeScript, que no brinda para trabajar con ellos y que beneficios tienen. Nuevamente utilizaremos VS Code en algunos ejemplos.

Objetivo

En esta sexto post tocaremos los temas: namespaces, módulos y decoradores, como se usan en TypeScript, que nos brinda para trabajar con ellos y que beneficios tienen. Nuevamente utilizaremos VS Code en algunos ejemplos.

Audiencia

Este documento está dirigido a personas que conocen muy poco o nada sobre el tema.o personas que desarrollan tareas de consultoría de desarrollo o que simplemente están interesados en leer e investigar sobre la tecnología alcanzada por esta publicación.

Desarrollo

Namespaces

Muchos lenguajes de programación como C#, Java y TypeScript nos brindan una forma de organizar nuestro codigo por medio de Namespaces. Usaremos estos namespaces para agrupar funcionalidades similares.

Supongamos que tenemos varias clases validadoras como en el ejemplo:

interface StringValidator {
isAcceptable(s: string): boolean;
}

let lettersRegexp = /^[A-Za-z]+$/;
let numberRegexp = /^[0-9]+$/;

class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}

class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 &amp;&amp; numberRegexp.test(s);
}
}

A medida que nuestra aplicación crezca tal vez es necesario agregar más validadores. Es un buena práctica tener nuestros validadores organizados en un Namespace. Por ahora, no le prestemos atención a la palabra export lo veremos más adelante.

namespace Validation {
export interface StringValidator {
isAcceptable(s: string): boolean;
}

const lettersRegexp = /^[A-Za-z]+$/;
const numberRegexp = /^[0-9]+$/;

export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}

export class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 &amp;&amp; numberRegexp.test(s);
}
}
}

Supongamos que no queremos hacer que todas nuestras validaciones estén el mismo archivo. TypeScript nos permite separarlos y hacer referencia al archivo donde se encuentra el namespace base

Validation.ts

namespace Validation {
export interface StringValidator {
isAcceptable(s: string): boolean;
}
}

LettersOnlyValidator.ts

/// &lt;reference path="Validation.ts" /&gt;
namespace Validation {
const lettersRegexp = /^[A-Za-z]+$/;
export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}
}

ZipCodeValidator.ts

/// &lt;reference path="Validation.ts" /&gt;
namespace Validation {
const numberRegexp = /^[0-9]+$/;
export class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 &amp;&amp; numberRegexp.test(s);
}
}
}

TestExamaple.ts

/// &lt;reference path="Validation.ts" /&gt;
/// &lt;reference path="LettersOnlyValidator.ts" /&gt;
/// &lt;reference path="ZipCodeValidator.ts" /&gt;

let strings = ["Hello", "98052", "101"];

let validators: { [s: string]: Validation.StringValidator; } = {};
validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();

for (let s of strings) {
for (let name in validators) {
console.log(""" + s + "" " + (validators[name].isAcceptable(s) ? " matches " : " does not match ") + name);
}
}

Módulos

Cada módulo tiene su propio ámbito, esto significa que todo su contenido, clases, variables, funciones, etc declaradas dentro no serán visibles al menos que se exporten. Es aquí la importancia de la palabra export, export dará visibilidad a las clases que quieran usarla  y para ser usados deben ser importados.

Los módulos pueden importarse entre sí por medio de un cargador de módulos. En nuestro caso estamos usando CommonJS pero podemos utilizar cualquier otro. Veamos un ejemplo supongamos que tenemos una clase que era un módulo:

customer.ts

class Customer{

let name: string;
GetName(){
return name;
}
}

export { Customer };

Simplemente por tener la palabra export ya se convertirá en un módulo. Export está diciendo que Customar podrá ser consumida o utilizada fuera del ámbito del propio módulo.

Para no exponer el nombre original podemos exportarlo como un alias de la siguiente manera:

export { Customer as PrincipalCustomer };

Ahora para utilizar en nuestra app el módulo Customer debemos importarlo de esta manera:

import{ Customer} from "./customer";

let myCustomer = new Customer();

Muchos pensaran “le fatla e .ts”. No es necesario ya que por default sabrá que se refiere a ese tipo de extensión. Supongamos que nuestro módulo posee más de una clase, y queremos importarlo en una variable

import * as list from "./customer";

let myCustomer = new list.Customer();

Una buena opción es exportarlo por default, cada módulo puede tener una y solo una exportación por default.

customer.ts

class Customer{
...
}

export default Customer;

app.ts

import Customer from "./customer";
let myCustomer = new Customer();

Realmente el uso de módulos es bastante sencillo. El tema es más extenso pero con esto nos alcanza para tener un excelente punto de partida.

Decoradores

Los decoradores vienen de Angular (2) y fueron solicitados por el equipo de Google. Si, aunque no lo crean, el equipo de Microsoft y el equipo de Google trabajaron juntos para poder implementarlo en TypeScript.

Antes que nada, para poder hacer uso de los decorator, debemos cambiar una configuración en nuestro tsconfig y agregar lo lo siguiente.

{
"compilerOptions": {
"target": "es5",  'ESNEXT'. */
"module": "commonjs",
"experimentalDecorators": true
}
}

aunque suene raro que diga experimental, en muchos lugares ya se usa en produccion asi que no debemos preocuparnos por esto.

Un decorador es un tipo especial de declaración que adjunta metadata o añadir una cierta característica que no deberían cambiar el comportamiento a una clase, método, propiedades o parámetros.

Para hacer un decorator debemos cumplir algunas especificaciones dependiendo de a cual queramos afectar.

type ClassDecorator = &lt;Function extends Function&gt;(target: TFunction: TFunction | void;
type MethodDecorator = &lt;T&gt;(target: Object, propertyKey: string | symbol, descriptor: TypedPrpoertyDescriptor&lt;T&gt;): void;
Type PropertyDecorator = (target: Object, propertyKey: string | symbol): void;
Type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number): void;

Para mejor su funcionamiento vamos a hacer un ejemplo donde tendremos una clase log que irá registrando el comportamiento de una clase.

function logClass(constructor: Function){
console.log(Date.now() + " - LogClass......: " + constructor["name"]);
}

function logMethod(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor&lt;T&gt;):void{
console.log(Date.now() + " - LogMethod.....: " + propertyKey.toString());
}

function logParameter(target: Object, propertyKey: string | symbol, parameterIndex: number):void{
console.log(Date.now() + " - LogParamter...: " + propertyKey.toString());
}

Lo que podemos ver en nuestra clase es que tenemos 3 funciones: una para class, otra para un method y por último para un parámetros. Ahora veamos cómo se vería nuestra clase decorada:

@logClass
class Calculadora{

constructor(){}

@logMethod
Sumar(arg1: number, @logParameter arg2: number){
return arg1 + arg2;
}

}

let calc = new Calculadora();
console.log(calc.Sumar(1,2));

El símbolo @ le dirá compilador que es un decorador.  Para ejecutar nuestro codigo primero debemos compilarlo con tsc y luego lo ejecutaremos con nodeJs desde la consola de VS Code.

tsc decorator.ts
node decorator.js

Conclusión

Hemos visto el uso  namespaces, módulos y decoradores. Nuevamente es simplemente una introducción y un buen punto de partida para comenzar a entrar más en profundidad. En los próximos post veremos un ejemplo de una aplicación sencilla, un abm, utilizando TypeScript junto a JQuery.