Subir archivos con Angular y WebApi



app.component.html

<form [formGroup]="form" (ngSubmit)="onSubmit()" class="form-horizontal form-control-sm">
  <div class="form-row">
    <label for="nombre" class="col-sm-1 control-label form-control-sm text-right">Nombre</label>
    <div class="col-sm-1">
      <input class="form-control form-control-sm" formControlName="nombre">
    </div>
  </div>

  <div class="form-row mb-2">
    <label for="foto" class="col-sm-1 control-label form-control-sm text-right">Foto</label>
    <div class="col-sm-3">
      <img src="./assets/noimage.png" id="previewFoto" name="previewFoto" style="width: 150px; height: 150px;cursor: pointer" onClick="document.getElementById('foto').click();"
      />
    </div>
    <input class="form-control form-control-sm" id="foto" type="file" accept=".xlsx" (change)="upload($event)"
      #fileInput style="display: none">
  </div>

  <input type="submit" value="Guardar" [disabled]="!form.valid" class="btn btn-primary col-sm-1">
</form>


app.component.ts

import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from "@angular/forms";
import { DatosService } from './_servicios/datos.service';
import { Datos } from './_modelos/datos';
import { CustomResponse } from './_modelos/custom-response';
import { ResponseMessageCode } from './_servicios/enumerados';
//import { Archivo } from './_modelos/archivo';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  datos = new Datos();
  form: FormGroup;

  constructor(private fb: FormBuilder, private data : DatosService) {
    this.createForm();
  }

  createForm() {
    this.form = this.fb.group({     
  nombre: [''],
      foto: ['']
    });
  }

  upload(event) {
    this.onFileChange(event);
  }

  onFileChange(event) {
    if (event.target.files.length > 0) {
      let archivoSeleccionado = event.target.files[0];

      let reader = new FileReader();
      reader.readAsDataURL(archivoSeleccionado);
      let _this = this;

      reader.onloadend = function () {
        _this.form.patchValue({
          foto: (<string>reader.result).split('base64,')[1]
        });
      }
    }
  }

  onSubmit() {       
    this.datos.nombre = this.form.get('nombre').value;

    if (this.datos.contenido != 'undefined') {
      this.datos.contenido = this.form.get('foto').value;
    }

    this.data.guardar(this.datos).subscribe(
      (response: CustomResponse<any>) => {
        if (response.messageCode == ResponseMessageCode.OK) {
          console.log("todo ok");
        } else {
          console.log("mal");     
        }
      }
    );
  }

  ngOnInit() {
  }
}


app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: 'home', component: AppComponent }
]

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule,
    RouterModule.forRoot(routes)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }



datos.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class DatosService {
  constructor(public http: HttpClient) { }

  public guardar(datos): Observable<any> {
    return this.http.post<any>("http://localhost/servicios/api/creditos/subirarchivo", datos);
  }
}

custom-response.ts

export class CustomResponse<T> {
   messageCode: number;
   message: string;
   data: T;
}

datos.ts

export class Datos {
    nombre: string;
    contenido: string;
}


WebApi C#

[AllowAnonymous]
[OverrideAuthentication]
[HttpPost]
public IHttpActionResult SubirArchivo(Arch datos)
{
var path = System.Web.HttpContext.Current.Server.MapPath("~") + @"\xls\archivo.xlsx";
if (File.Exists(path))
File.Delete(path);

File.WriteAllBytes(path, datos.Contenido);

var mensaje = new { error = false, mensaje = "" };

return this.Ok(mensaje);
}

public class Arch
{
    [JsonProperty("nombre")]
    public string Nombre { get; set; }
    [JsonProperty("contenido")]
    public byte[] Contenido { get; set; }
}

no se puede cargar el archivo o ensamblado Microsoft.AI.Web...

Opcion 1:

Eliminar el contenido de la carpeta que se llame igual que el sitio que esta dando el problema, en esta carpeta (ej, si fuera el sitio creditos):

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\creditos


Opción 2:

Instalar con NuGet:

Microsoft.ApplicationInsights (version 2.7.2)

y

Microsoft.ApplicationInsights.Web (version 2.7.2)

Este ultimo es el que contiene el archivo que resuelve el error: Microsoft.AI.Web.dll


Crear un paquete custom con NuGet

Ejemplo: crear un paquete para prueba.dll

mkdir c:\temp\prueba
mkdir c:\temp\prueba\lib
mkdir c:\temp\prueba\lib\net45

copy prueba.dll c:\temp\prueba\lib\net45

nuget spec prueba
nuget pack prueba.nuspec


<?xml version="1.0"?>
<package >
  <metadata>
    <id>prueba</id>
    <version>1.0.0</version>
    <authors>carusso</authors>
    <owners>carusso</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>prueba</description>
    <releaseNotes></releaseNotes>
    <copyright></copyright>
    <tags></tags>
    <dependencies>
      <dependency id="SampleDependency" version="1.0" />
    </dependencies>
  </metadata>
</package>


Firebase Ionic Angular

ionic start ejemplo1 blank --type=angular
cd ejemplo1
npm install angularfire2 firebase

crear un archivo credentials.ts y agregarle el codigo que aparece en la consola de firebase:
(en la ruedita de configuracion, al lado del texto "Descripcion general..." luego en el icono </>)

export var firebaseConfig = {
    apiKey: "AIzaSyA1LFnrg7kJ7bevnFIVcNDIxxxxxxxxxxxxxx",
    authDomain: "prueba2-b3344.xxxxxxxxxxxxxxxx.com",
    databaseURL: "https://prxxxxxxxxxxx44.fxxxxxxxxxxxxxxxxeio.com",
    projectId: "pruexxxxxxxxxxxxxxxxx",
    storageBucket: "pxxxxxxxxxxxxxxxxx.com",
    messagingSenderId: "398794336943"
};


app.module.ts:

import { AngularFireModule } from 'angularfire2';
import { AngularFirestoreModule } from 'angularfire2/firestore';
import { AngularFireStorageModule } from 'angularfire2/storage';
import { firebaseConfig } from './credentials';

  imports: [
    AngularFireModule.initializeApp(firebaseConfig),
    AngularFirestoreModule,
    AngularFireStorageModule
  ],

Crear una interfaz competidor.ts:

export class Competidor {
    id: string;
    numero: number;
    nombre: string;
    apellido: string;
}

Crear un servicio:

ng generate service firestore-service

firestore-service.ts

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Competidor } from '../_modelos/competidor';

@Injectable({
  providedIn: 'root'
})

export class FirestoreServiceService {
  constructor(public firestore: AngularFirestore) {}

  buscarCompetidor(id: string): AngularFirestoreDocument<Competidor> {
    return this.firestore.collection(`competidores`).doc(id);
  }

  actualizarCompetidor(comp: Competidor): Promise<void> {
    return this.firestore.doc(`competidores/${comp.id}`).update({       
      numero: comp.numero,
      nombre: comp.nombre,
      apellido: comp.apellido
    }); 
  }

  guardarCompetidor(comp: Competidor): Promise<void> {
      const id = this.firestore.createId(); 

      return this.firestore.doc(`competidores/${id}`).set({
        id: id,
        numero: comp.numero,
        nombre1: comp.nombre,
        apellido1: comp.apellido
      }); 
  }

  listaCompetidores(): AngularFirestoreCollection<Competidor> {
    return this.firestore.collection(`competidores`); 
  }
}

Guardar y recuperar imagenes

competidor.component.html

      <div>
        <img src="./assets/noimage.png" id="previewFoto" name="previewFoto" style="width: 150px; height: 150px;cursor: pointer" onClick="document.getElementById('foto').click();" />
      </div>
<input class="form-control form-control-sm" id="foto" type="file" accept=".png,.jpg,.jpeg" (change)="upload($event)"
          #fileInput style="display: none">

competidor.component.ts
import { FirestoreServiceService } from '../../../_servicios/firestore-service.service';
import { AngularFireStorage } from 'angularfire2/storage';


  constructor(private http: Http, private fb: FormBuilder, private route: ActivatedRoute,
              private router: Router, private data : CompetidoresService, private fbservice: FirestoreServiceService,
              private storage: AngularFireStorage) {
    let id = null;

    this.createForm();

    this.route.params.subscribe(params => {         
      id = params["id"];   
    });     

   this.form.patchValue({id: id});

    if (id != 0)
    {   
      this.fbservice.buscarCompetidor(id).valueChanges().subscribe((datos) => {
        let competidor = datos;
                   
        this.form.patchValue({
          id: competidor.id,
          numero: competidor.numero,
          nombre: competidor.nombre,
          apellido: competidor.apellido
          foto: competidor.foto
        });

        document["previewFoto"].src = competidor.foto;   
      });     
    }
  }


  upload(event) {
    this.fotoAux = event.target.files[0];

    if (event.target.files.length > 0) {
      let file = event.target.files[0];

      var preview = document.querySelector('img');   
      var reader  = new FileReader();
 
      reader.onloadend = function () {     
        preview.src = reader.result.toString();
      }
 
      if (file) {
        reader.readAsDataURL(file);
      } else {
        preview.src = "";
      }
    }
  }

onSubmit() {
         let idImagen = this.form.get("nombre1").value + "_" + this.form.get("apellido1").value;
         this.storage.upload(`/mko/imagenes/${idImagen}`, this.fotoAux);

         let downloadURL =       
                  this.storage.ref(`/mko/imagenes/${idImagen}`).getDownloadURL().subscribe(d => {

         this.form.patchValue({foto: d}); 
         comp.foto = this.form.get("foto").value;

          this.fbservice.buscarCompetidor(comp.id).valueChanges().subscribe(d => {
          if (!d) {   
             this.fbservice.guardarCompetidor(comp).then(() => {
             this.router.navigate(['/competidores/lista']);
           });
         } else
        {
           this.fbservice.actualizarCompetidor(comp).then(() => {
           this.router.navigate(['/competidores/lista']);
        });
     }   
   });
  });
}


Slideshow con Adobe Premiere Pro CC 2015

1. Crear secuencia

New project / File / New Sequence
HDV / HDV 1080p25

2. Importar carpeta de fotos

File / Import

3. Set default transition

Efectos / Transiciones de video / Elegir una, y luego click derecho y set default transition

4. Automatizar la secuencia


Bajar archivo desde WebApi con Angular 6


WebApi:

[HttpGet]
public HttpResponseMessage GenExcel()
{
var rutaExcelTemp = @"C:\path_del_sitio_web\Xls\TasaMedia.xlsx";

var nombreArchivoGenerado = "TasaMedia_" + DateTime.Now.Day + "_" + DateTime.Now.Month + "_" + DateTime.Now.Year + "_" + DateTime.Now.Hour + DateTime.Now.Minute + DateTime.Now.Second + DateTime.Now.Millisecond + ".xlsx";//nombre del nuevo archivo

var reportStream = new StreamContent(File.Open(rutaExcelTemp, FileMode.Open, FileAccess.Read));

var result = Request.CreateResponse(HttpStatusCode.OK);

result.Content = reportStream;

result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/force-download");
result.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
result.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment")
{
FileName = Path.GetFileName(nombreArchivoGenerado)
};
return result;     
}



Angular:

  import { Observable } from 'rxjs';
  import { HttpClient } from "@angular/common/http";

  downloadFile(url: string) {
    return this.http.get('http://localhost' + url', {
      responseType: 'blob', observe: 'response'
    }).subscribe(res => {
      let contentDisposition = res.headers.get('Content-Disposition');
      var result = contentDisposition.split(';')[1].trim().split('=')[1];
      let archivo = result.replace(/"/g, '');

      console.log('start download:', res);
      var url = window.URL.createObjectURL(res.body);
      var a = document.createElement('a');
      document.body.appendChild(a);
      a.setAttribute('style', 'display: none');
      a.href = url;
      a.download = archivo; //res.filename;
      a.click();
      window.URL.revokeObjectURL(url);
      a.remove(); // remove the element
    }, error => {
      console.log('download error:', JSON.stringify(error));
    }, () => {
      console.log('Completed file download.')
    });
  }

Actualizacion a Angular 6 desde 5.2

1. npm install -g @angular/cli
2. npm i -g npm
3. npm install @angular/cli
4. ng update @angular/cli
5. npm install --save-dev @angular/cli@latest
6. ng update @angular/cli
7. ng update @angular/core
8. ng update @angular/material
9. ng update
10. npm install -g rxjs-tslint
11. rxjs-5-to-6-migrate -p src/tsconfig.app.json
12. npm uninstall rxjs-compat
13. cerrar y abrir visual code


https://blog.ng-classroom.com/blog/angular/Angular-upgrade/?utm_source=browser&utm_medium=push_notification&utm_campaign=PushCrew_notification_1525897317&pushcrew_powered=1


Ejemplo de ObjGen

Ejemplo (pegarlo en http://www.objgen.com/json)

version n = 3.1
releaseDate d = 2014-06-25
demo b = true

// Tabs or spaces define complex values
person
  id number = 12345
  name = John Doe
  phones
    home = 800-123-4567
    mobile = 877-123-1234

  // Use [] to define simple type arrays
  email[] s = jd@example.com, jd@example.org
  dateOfBirth d = 1980-01-02
  registered b = true

  // Use [n] to define object arrays
  emergencyContacts[0]
    name s = Jane Doe
    phone s = 888-555-1212
    relationship = spouse
  emergencyContacts[1]
    name s = Justin Doe
    phone s = 877-123-1212
    relationship = parent

Tfs API - Obtener items [*** 100% funcionando ***]

(fuente para el tema de autenticacion: https://stackoverflow.com/questions/3150260/how-do-you-connect-to-a-tfs-server-in-c-sharp-using-specific-credentials/3150730#3150730)

Instalar con NuGet:

* Microsoft.TeamFoundationServer.ExtendedClient (version 15) ==> agregar todo


* Microsoft.VisualStudio.Services.Client (version 15) ==> se necesita Microsoft.TeamFoundation.Common.dll


* Microsoft.TeamFoundationServer.Client.(version 15) ==> se necesita Microsoft.VisualStudio.Services.WebApi.dll


Ejemplo de uso:

static void Main(string[] args)
{
var urlTfs = "http://Xvir29:8080/tfs";
var workspaceTfs = "X00894";
var pathLocal = @"c:\crusso\X\fuentes";
var teamProject = "Desarrollo";
var usuario = "carusso";
var password = "elpassword";

GetSourceFromTFS(urlTfs, workspaceTfs, pathLocal, teamProject, "WebCreditos", usuario, password);
}



public void GetSourceFromTFS(string urlTfs, string workspaceTfs, string pathLocal, string teamProject, string proyecto, string usuario, string password)
{
var collectionUri = new Uri(urlTfs);

NetworkCredential credential = new NetworkCredential(usuario, password);

NetworkCredential netCred = new NetworkCredential(usuario, password);
var winCred = new Microsoft.VisualStudio.Services.Common.WindowsCredential(netCred);
VssCredentials vssCred = new VssClientCredentials(winCred);
vssCred.PromptType = CredentialPromptType.DoNotPrompt;

Uri tfsUri = new Uri(urlTfs);
var tfs = new TfsTeamProjectCollection(tfsUri, vssCred);         
tfs.EnsureAuthenticated();


var vsStore = tfs.GetService<VersionControlServer>();

var path = pathLocal + "\\" + teamProject + "\\" + proyecto;
var items = vsStore.GetItems("$\\" + teamProject + "\\" + proyecto, VersionSpec.Latest, RecursionType.Full);

var workspace = vsStore.GetWorkspace(workspaceTfs, usuario);

workspace.Get(new string[] { path }, VersionSpec.Latest, RecursionType.Full, GetOptions.GetAll);
}



Compilar desde una aplicacion Web utilizando API build tools

Referencias que se necesitan:
Microsoft.Build
Microsoft.Build.Engine
Microsoft.Build.Framework

Estas dll's se encuentran en C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\

si no aparecen, instalarlos asi:
vs_buildtools.exe --add Microsoft.VisualStudio.Workload.WebBuildTools

o bajarlo de aca: https://www.visualstudio.com/es/thank-you-downloading-visual-studio/?sku=BuildTools&rel=15


using System.Collections.Generic;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Execution;
using System.IO;
using Microsoft.Build.Framework;

            var exitcode = 0;

            string projectFileName = @"C:\crusso\X\fuentes\Desarrollo\WebCreditos\WebCreditos.sln";
            ProjectCollection pc = new ProjectCollection();
            Dictionary<string, string> GlobalProperty = new Dictionary<string, string>();
            GlobalProperty.Add("Configuration", "Release");
            GlobalProperty.Add("Platform", "Any CPU");
            GlobalProperty.Add("OutputPath", Directory.GetCurrentDirectory() + "\\deploy");

            Microsoft.Build.BuildEngine.FileLogger fl = new Microsoft.Build.BuildEngine.FileLogger() { Parameters = @"logfile=c:\temp\log.txt" };

            BuildParameters bp = new BuildParameters(pc);
           
            bp.Loggers = new[] {
                                  new Microsoft.Build.BuildEngine.FileLogger
                                  {
                                    Verbosity = LoggerVerbosity.Normal,
                                    ShowSummary = true,
                                    SkipProjectStartedText = true,
                                    Parameters = @"logfile=c:\temp\log.txt"
                                  }
                                };
           
            BuildManager.DefaultBuildManager.BeginBuild(bp);
            BuildRequestData BuildRequest = new BuildRequestData(projectFileName, GlobalProperty, null, new string[] { "Build" }, null);
            BuildSubmission BuildSubmission = BuildManager.DefaultBuildManager.PendBuildRequest(BuildRequest);
            BuildSubmission.Execute();
            BuildManager.DefaultBuildManager.EndBuild();

            if (BuildSubmission.BuildResult.OverallResult == BuildResultCode.Failure)
            {
                exitcode = 1; //error
                //throw new Exception();
            }
            else
                exitcode = 0;

            return exitcode

Leer una imagen de mysql y mostrarla en Angular

en este ejemplo, foto es el campo leido de mysql, tiene un atributo data que es la imagen codificada.

var preview = document.querySelector('img');                           
var arrayBufferView = new Uint8Array(foto.data);
var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
var urlCreator = window.URL;
var imageUrl = urlCreator.createObjectURL(blob);       
preview.src = imageUrl;



Validaciones custom con Angular 5


app.component.html

<form [formGroup]="agendaForm" (ngSubmit)="submit()">
  <input formControlName="usuario">
  <input formControlName="telefono">

  <div *ngIf="agendaForm.get('usuario').errors">
     <div *ngIf="agendaForm.get('usuario').errors['required']">
          Nombre de usuario es requerido
     </div>
  </div>

  <div *ngIf="!agendaForm.valid">
       Hay errores en el form!!!
  </div>

  <button type="submit" [disabled]="!agendaForm.valid">Enviar</button>
</form>

app.component.ts

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  agendaForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.crearForm();
  }

  crearForm() {
    this.agendaForm = this.fb.group({
      usuario: ['texto precargado', Validators.required],
      telefono: ['', Validators.compose(
                        [Validators.required,
                         this.telefonoValidator(/^[679]{1}[0-9]{8}$/)
                        ]
                      )
                ]             
    });
  }

  telefonoValidator(telefonoExp: RegExp): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} => {
      const telefono = telefonoExp.test(control.value);
      return !telefono ? {'telefonoNumber': {value: control.value}} : null;
    };
  }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent    
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }