Explicacion De .netcore.docx

  • Uploaded by: ANDRES
  • 0
  • 0
  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Explicacion De .netcore.docx as PDF for free.

More details

  • Words: 2,046
  • Pages: 13
Construccion de proyecto web y mobil

1. Crear una nueva solución en blanco, con nombre Shop. Con esto la tenemos el lienzo 2. Crear en la solución un proyecto .Net Standart; lo llamamos con el nombre del proyecto Shop.Common. con esto ya tenemos:

3. Ahora continuando con las partes del frontend y Backend, creamos carpetas para cada uno. (Frontend) y (Backend). 4. Dentro del proyecto Backend creamos un proyecto ASP.NET Core Web Application, con el nombre Shop.Web de forma model view controller habilitando el HTTPS, y seleccionando el .NET Core. Con esto ya tendremos

5. Dentro del proyecto Frontend creamos dos subcarpetas (Form) y (Classic) 6. Dentro de la subcarpeta Forms creamos nuevo proyecto Mobile App (Xamarin.Forms) con el nombre Shop.UIForms en blanco para Android y para IOS. 7. El visual me deja por fuera dos proyectos: el Shop.UIForms y el Shop.UIForms.IOS; los movemos a la subcarpeta Forms. Con esto ya tendremos

8. En la carpeta Classic creamos un nuevo proyecto Class library (.NET Standart) con el nombre Shop.UIClassic 9. Dentro de la misma carpeta creamos un nuevo proyecto Android App (Xamarin) con el nombre Shop.UIClassic.Android en blanco 10. Dentro de la misma carpeta creamos un nuevo proyecto IOS App (Xamarin) con el nombre Shop.UIClassic.IOS en blanco, para universal en versión 12.1. Asi tenemos

Hasta tener esta estructura

Creación de la base de datos 1. Dentro del proyecto Shop.Web crear una carpeta que se llame (Data). 2. Dentro de Data Crear una carpeta que se llame (Entities). 3. Dentro de Entities crear una nueva clase que se llame Products. En esta clase es donde creamos la base de datos 4. Es recomendable pasar los using dentro de manespace. 5. Explicación del código: public class Product {

public int Id { get; set; }

[MaxLength(50, ErrorMessage = “Mensaje que quiere que salga”)] [Required]

Commented [A1]: Id es la primary key del product y por defecto el Framework lo hace auto incrementable Commented [A2]: Exige un tamaño

public string Name { get; set; } [DisplayFormat(DataFormatString = "{0:C2}", ApplyFormatInEditMode = false)] public decimal Price { get; set; } [Display(Name = "Image")] public string ImageUrl { get; set; } [Display(Name = "Last Purchase")] public DateTime? LastPurchase { get; set; } [Display(Name = "Last Sale")] public DateTime? LastSale { get; set; } [Display(Name = "Is Availabe?")] public bool IsAvailabe { get; set; } [DisplayFormat(DataFormatString = "{0:N2}", ApplyFormatInEditMode = false)] public double Stock { get; set; } }

Commented [A3]: Al poner esto el campo se vuelve obligatorio para la BD y para la API Commented [A4]: DisplayFormat da formato el campo, {0} formato de moneda que tenga el equipo configurado, {c2} separador de miles poniéndole dos decimales Commented [A5]: para que el usuario lo vea como image y el programador como imageURL

Commented [A6]: El isgno de interrogacion es para volver nulable el campo en la table de la base de datos.

Commented [A7]: cuanta catidad tengo en inbentario de ese product {0:N2} pone separadores de miles y marca los decimales

6. Dentro de la carpeta Data crear una clase que se llame DataContext. Es la clase que marca la conexión con la base de datos. 7. Explicacion DataContext using Common.Models; using Microsoft.EntityFrameworkCore; public class DataContext : DbContext { public DbSet Products { get; set; }

Commented [A8]: Hereda de la clase EntityFrameworkCore

public DataContext(DbContextOptions options) : base(options) { } }

Commented [A9]: crear la propiedades que estan en la clase Product y le doy el numbre en singular de Products y ya los datos no se los paso como si fueran tablas sino como una colección de objetos por la propiedad Products

8. Ahora en la AppSetting.Json definimos la cadena de conexión a la base de datos { "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": {

"DefaultConnection": "Server=(localdb)\\ProjectsV13;Database=Shop;Trusted_Connection=True;Mult ipleActiveResultSets=true" } }

9. Configuramos la inyeccion de dependecias de la base de datos en el proyecto Strarup.cs y en la configuración del proyecto antes de los cookies agregamos la conexión con services.AddDbContext(cfg => { cfg.UseSqlServer(this.Configuration.GetConnectionString("DefaultConnection")); }); DefaultConnection es el nombre con el que definio en nombre de la conexion en el archive json donde esta la conexion de la base de datos

10. Para crear o instanciar un nuevo servidor DB lo creamos por comandos del sistema asi para en este caso “ProjectsV13”

11. Para crear la base de datos Shop en este servidor lo hacemos por comandos del sistema

Asi ya tenemos la base de datos creada con todas las propiedades. 12. En la carpeta Controller creamos un nuevo controlador (Controlador de MCV con vistas que usan Entities Framework). Clase de modelo: product. Clase de contexto: DataContext. Con esto ya creamos el ProductController junto con las vistas Create Delete Details Edit, update. Que están dentro de la carpeta View. 13. En el archivo _Layout adicionamos un nuevo menú Product en el var.
  • Product


  • Nota “Si se haceb cambioi a las entidades de la clase a la base de datos se debe actualizar la base de datos con: Dotnet ef migrations add ModifyProducts Dotnet ef database update”. 14. Seed DB => el alimentador de la base de datos. Lo que hace esta clase es añadir datos a la base de datos en todo momento que la base de datos sea eliminada para no tener que crear datos manualmente cada que se elimine la BD. También sirve para data generical como por ejemplo todas las ciudades de Colombia; que cada que la BD se elimina esta clase me adicione nuevamente todas las ciudades. En la carpeta Data de la carpeta BackEnd Adicionamos una nueva clase que la llamamos SeedDB using System; using System.Linq; using System.Threading.Tasks; using Common.Models; public class SeedDb { private readonly DataContext context; private Random random; public SeedDb(DataContext context) { this.context = context; this.random = new Random(); } public async Task SeedAsync() { await this.context.Database.EnsureCreatedAsync();

    if (!this.context.Products.Any()) { this.AddProduct("First Product"); this.AddProduct("Second Product"); this.AddProduct("Third Product"); await this.context.SaveChangesAsync(); } } private void AddProduct(string name) { this.context.Products.Add(new Product { Name = name, Price = this.random.Next(100), IsAvailabe = true, Stock = this.random.Next(100) }); } } Para que los datos que ponemos en la clase Seed sean ingresadas a la base de datos debemos cambiar el programa para que esta clase sea tenida en cuenta en el arranque. Esto lo hacemos modificando la clase Program con este código. 15. Modify the Program class by: using Data; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; public class Program { public static void Main(string[] args) { var host = CreateWebHostBuilder(args).Build(); RunSeeding(host); host.Run(); } private static void RunSeeding(IWebHost host) { var scopeFactory = host.Services.GetService(); using (var scope = scopeFactory.CreateScope()) { var seeder = scope.ServiceProvider.GetService<SeedDb>(); seeder.SeedAsync().Wait(); }

    Commented [A10]: Aqui le decimos al programa que use la clase seed

    } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); }

    16. Lo añadimos a el startup Services..AddTransient<SeedDb>(); 17. Implement the pattern repository

    Cambiamos los controladores para que directamente no acceda a la base de datos por medio del datacontext, sino que los controladores acceda a la clase que llamaremos repositorio y luego el repositorio es el que va acceder a la base de datos, para que en determinado momento yo pueda engañar los controladores y cambiar las conexiones a las bases de datos. Agregamos una nueva clase en la carpeta Data con el nombre Repository. using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Common.Models; public class Repository { private readonly DataContext context; public Repository(DataContext context) { this.context = context; } public IEnumerable GetProducts() { return this.context.Products.OrderBy(p => p.Name); } public Product GetProduct(int id) { return this.context.Products.Find(id); } public void AddProduct(Product product) { this.context.Products.Add(product); }

    Commented [A11]: Inicializa el context del DataContext

    Commented [A12]: Contructor Commented [A13]: Devuelve una lista de productos no instanciada Commented [A14]: Context: conexxion a la DB Products: Tabla OrderBy: devuelvalos ordenados. P => p.Name: exprecion linkq para los nombres Commented [A15]: Retorna un objeto de la clase Product donde le pasamos por parameto un id

    Commented [A16]: Adicionamos un Nuevo producto

    public void UpdateProduct(Product product) { this.context.Update(product); }

    Commented [A17]: Actualizamos un producto

    public void RemoveProduct(Product product) { this.context.Products.Remove(product); }

    Commented [A18]: Elimina un product de este producto

    public async Task SaveAllAsync() { return await this.context.SaveChangesAsync() > 0; }

    Commented [A19]: Los metodos anteriores dejan la transaccion pendiente hasta que sea ejecutado este metodo que guarda los cambios en la base de datos. Este método es asíncrono por eso tiene el async

    public bool ProductExists(int id) { return this.context.Products.Any(p => p.Id == id); } }

    18. Para crear la interfaz del repositorio le damos clic derecho en la clase (Acciones rápidas y refactorizables) clic en (Extraer interfaz) 19. Cambiamos el código del ProductsController para que acceda al IRepository using Data; using Data.Entities; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Threading.Tasks; public class ProductsController : Controller { private readonly IRepository repository; public ProductsController(IRepository repository) { this.repository = repository; } public IActionResult Index() { return View(this.repository.GetProducts()); } public IActionResult Details(int? id) { if (id == null)

    Commented [A20]: Espera a que los grave los cambion en la base de datos Commented [A21]: Devuelve verdadero si existe o falso si ep product no existe

    { return NotFound(); } var product = this.repository.GetProduct(id.Value); if (product == null) { return NotFound(); } return View(product); } public IActionResult Create() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task Create(Product product) { if (ModelState.IsValid) { this.repository.AddProduct(product); await this.repository.SaveAllAsync(); return RedirectToAction(nameof(Index)); } return View(product); } public IActionResult Edit(int? id) { if (id == null) { return NotFound(); } var product = this.repository.GetProduct(id.Value); if (product == null) { return NotFound(); } return View(product); } [HttpPost] [ValidateAntiForgeryToken] public async Task Edit(Product product)

    { if (ModelState.IsValid) { try { this.repository.UpdateProduct(product); await this.repository.SaveAllAsync(); } catch (DbUpdateConcurrencyException) { if (!this.repository.ProductExists(product.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } return View(product); } public IActionResult Delete(int? id) { if (id == null) { return NotFound(); } var product = this.repository.GetProduct(id.Value); if (product == null) { return NotFound(); } return View(product); } [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task DeleteConfirmed(int id) { var product = this.repository.GetProduct(id); this.repository.RemoveProduct(product); await this.repository.SaveAllAsync(); return RedirectToAction(nameof(Index)); } }

    20. Configurar la inyección del repositorio y para el SeedDb en el startup services.AddTransient<SeedDb>(); services.AddScoped(); 21. Add

    User Identities. Creamos una nueva clase en la carpeta Data/Entities con el nombre User.

    Commented [A22]: El AddTransident tiene un ciclo de vida mas corto; se usa y se destruye. Commented [A23]: AddScoped La inyeccion queda permanente durante toda la ejecucion para que sea utilizada las veces que sea necesaria

    Esta clase hereda de la clase IdentityUser. La clase IdentityUser son los usuarios del sistema using Microsoft.AspNetCore.Identity; public class User : IdentityUser { public string FirstName { get; set; } public string LastName { get; set; } } 22. Modificamos la clase DataContext porque ya no va a heredar de ContextDb sino de IdentityDbContext<User>

    using Entities; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; public class DataContext : IdentityDbContext<User> { public DbSet Products { get; set; } public DataContext(DbContextOptions options) :base(options) { } } 23. Para crear una relación de uno a muchos de la clase Product a la clase User, en la clase Product adicionamos

    public User User { get; set; } 1. Drop the database and add the new migrations with those commands: dotnet ef database drop dotnet ef migrations add Users dotnet ef database update En la clase SeedDb sebemos decirle que herede también

    public SeedDb(DataContext context, UserManager<User> userManager) { var user = await this.userManager.FindByEmailAsync("[email protected]");

    Commented [A24]: Añadimos la clase User para que lo tome en cuenta junto con todas la tablas de seguridad del sistema

    if (user == null) { user = new User { FirstName = "Juan", LastName = "Zuluaga", Email = "[email protected]", UserName = "[email protected]" }; var result = await this.userManager.CreateAsync(user, "123456"); if (result != IdentityResult.Success) { throw new InvalidOperationException("Could not create the user in seeder"); } } if (!this.context.Products.Any()) { this.AddProduct("First Product", user); this.AddProduct("Second Product", user); this.AddProduct("Third Product", user); await this.context.SaveChangesAsync(); } } private void AddProduct(string name, User user) { this.context.Products.Add(new Product { Name = name, Price = this.random.Next(100), IsAvailabe = true, Stock = this.random.Next(100), User = user }); } } 24. En el startup confuguramos y adicionamos 25. services.AddIdentity<User, IdentityRole>(cfg => 26. { 27. cfg.User.RequireUniqueEmail = true; 28. cfg.Password.RequireDigit = false; 29. cfg.Password.RequiredUniqueChars = 0; 30. cfg.Password.RequireLowercase = false; 31. cfg.Password.RequireNonAlphanumeric = false; 32. cfg.Password.RequireUppercase = false; 33. })

    34.

    .AddEntityFrameworkStores();

    { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAuthentication(); app.UseCookiePolicy(); app.UseMvc(routes => {

    Related Documents

    Explicacion
    November 2019 57
    Explicacion
    May 2020 29
    Explicacion
    May 2020 45
    Saregune Explicacion
    August 2019 41

    More Documents from ""