Publicada:

.NET 6.0 - Ejemplo y tutorial de API CRUD

Tutorial creado con .NET 6.0

Otras versiones disponibles:

En este tutorial, mostraremos cómo crear una API .NET 6.0 que admita operaciones CRUD. La API de ejemplo incluye rutas para recuperar, actualizar, crear y eliminar registros en la base de datos, los registros en la aplicación de ejemplo son para usuarios, pero esto es solo para fines de demostración, el mismo patrón CRUD y estructura de código podrían usarse para administrar cualquier tipo de datos, por ejemplo productos, servicios, artículos, etc.

Base de datos EF Core InMemory utilizada para las pruebas

Para mantener el código API lo más simple posible, está configurado para usar el proveedor de base de datos EF Core InMemory que permite a Entity Framework Core crear y conectarse a una base de datos en memoria en lugar de tener que instalar un servidor de base de datos real. Esto se puede cambiar fácilmente a un proveedor de base de datos real cuando esté listo para trabajar con una base de datos como SQL Server, Oracle, MySQL, etc. Para obtener instrucciones sobre cómo conectarlo a una base de datos de SQL Server, consulte .NET 5.0 - Connect to SQL Server with Entity Framework Core, para MySQL consulte .NET 5.0 - Connect to MySQL Database with Entity Framework Core.

Código en GitHub

El proyecto del tutorial está disponible en GitHub en https://github.com/cornflourblue/dotnet-6-crud-api.


Contenido del tutorial de .NET 6.0 CRUD


Herramientas necesarias para ejecutar localmente la API de tutorial de .NET 6.0

Para desarrollar y ejecutar aplicaciones .NET 6.0 localmente, descargue e instale lo siguiente:

  • SDK de .NET : incluye el tiempo de ejecución de .NET y las herramientas de línea de comandos
  • Visual Studio Code - editor de código que se ejecuta en Windows, Mac y Linux
  • Extensión de C# para Visual Studio Code: agrega compatibilidad con VS Code para desarrollar aplicaciones .NET


Ejecute la API de ejemplo de .NET 6.0 CRUD localmente

  1. Descargue o clone el código del proyecto del tutorial desde https://github.com/cornflourblue/dotnet-6-crud-api
  2. Inicie la API ejecutando dotnet run desde la línea de comando en la carpeta raíz del proyecto (donde se encuentra el archivo WebApi.csproj), debería ver el mensaje Now listening on: http://localhost:4000.
  3. Siga las instrucciones a continuación para probar con Postman o conectarse con una de las aplicaciones de ejemplo de una sola página disponibles (Angular o React).

Comenzando en modo de depuración

También puede iniciar la aplicación en modo de depuración en VS Code abriendo la carpeta raíz del proyecto en VS Code y presionando F5 o seleccionando Depurar -> Inicie la depuración desde el menú superior, ejecutar en modo de depuración le permite adjuntar puntos de interrupción para pausar la ejecución y recorrer el código de la aplicación. Para obtener instrucciones detalladas, incluido un breve video de demostración, consulte VS Code + .NET - Debug a .NET Web App in Visual Studio Code.


Pruebe la API CRUD de .NET 6.0 con Postman

Postman es una gran herramienta para probar API, puede descargarla en https://www.postman.com/downloads.

A continuación, encontrará instrucciones sobre cómo usar Postman para realizar las siguientes acciones:


Cómo crear un nuevo usuario con Postman

Para crear un nuevo usuario con la API CRUD siga estos pasos:

  1. Abra una nueva pestaña de solicitud haciendo clic en el botón más (+) al final de las pestañas.
  2. Cambie el método HTTP a POST con el selector desplegable a la izquierda del campo de entrada de URL.
  3. En el campo URL ingrese la dirección de la ruta de los usuarios de su API local - http://localhost:4000/users
  4. Seleccione la pestaña Body debajo del campo URL, cambie el botón de opción de tipo de cuerpo a raw y cambie el selector desplegable de formato a JSON .
  5. Ingrese un objeto JSON que contenga las propiedades de usuario requeridas en el área de texto Body, por ejemplo:
    {
        "title": "Mr",
        "firstName": "George",
        "lastName": "Costanza",
        "role": "User",
        "email": "[email protected]",
        "password": "george-likes-spicy-chicken",
        "confirmPassword": "george-likes-spicy-chicken"
    }
  6. Haga clic en el botón Send, debería recibir "200 OK" respuesta con el mensaje "User created" en el cuerpo de la respuesta.

Aquí hay una captura de pantalla de Postman después de enviar la solicitud y crear el usuario:

Volver al principio


Cómo recuperar una lista de todos los usuarios con Postman

Para obtener una lista de todos los usuarios de la API CRUD de .NET 6, siga estos pasos:

  1. Abra una nueva pestaña de solicitud haciendo clic en el botón más (+) al final de las pestañas.
  2. Cambie el método HTTP a GET con el selector desplegable a la izquierda del campo de entrada de URL.
  3. En el campo URL ingrese la dirección de la ruta de los usuarios de su API local - http://localhost:4000/users
  4. Haga clic en el botón Send, debería recibir "200 OK" respuesta que contiene una matriz JSON con todos los registros de usuario en el sistema.

Aquí hay una captura de pantalla de Postman después de realizar una solicitud para obtener todos los usuarios:

Volver al principio


Cómo recuperar un usuario por ID con Postman

Para obtener un usuario específico por ID de la API CRUD de .NET 6, siga estos pasos:

  1. Abra una nueva pestaña de solicitud haciendo clic en el botón más (+) al final de las pestañas.
  2. Cambie el método HTTP a GET con el selector desplegable a la izquierda del campo de entrada de URL.
  3. En el campo URL, ingrese la dirección de la ruta /users/{id} con la identificación del usuario que desea recuperar, por ejemplo: http://localhost:4000/users/1
  4. Haga clic en el botón Send, debería recibir "200 OK" respuesta que contiene un objeto JSON con los detalles del usuario especificado.

Aquí hay una captura de pantalla de Postman después de realizar una solicitud para obtener un usuario por ID:

Volver al principio


Cómo actualizar un usuario con Postman

Para actualizar un usuario con la API CRUD, siga estos pasos:

  1. Abra una nueva pestaña de solicitud haciendo clic en el botón más (+) al final de las pestañas.
  2. Cambie el método HTTP a PUT con el selector desplegable a la izquierda del campo de entrada de URL.
  3. En el campo URL ingrese la dirección a la ruta /users/{id} con la identificación del usuario que desea actualizar, por ejemplo, http://localhost:4000/users/1
  4. Seleccione la pestaña Body debajo del campo URL, cambie el botón de opción de tipo de cuerpo a raw y cambie el selector desplegable de formato a JSON .
  5. Ingrese un objeto JSON en el área de texto Body que contenga las propiedades que desea actualizar, por ejemplo, para actualizar el nombre y el apellido:
    {
        "firstName": "Art",
        "lastName": "Vandelay"
    }
  6. Haga clic en el botón Send, debería recibir "200 OK" respuesta con el mensaje "User updated" en el cuerpo de la respuesta.

Aquí hay una captura de pantalla de Postman después de enviar la solicitud y actualizar al usuario:

Volver al principio


Cómo eliminar un usuario con Postman

Para eliminar un usuario con la API sigue estos pasos:

  1. Abra una nueva pestaña de solicitud haciendo clic en el botón más (+) al final de las pestañas.
  2. Cambie el método HTTP a DELETE con el selector desplegable a la izquierda del campo de entrada de URL.
  3. En el campo URL ingrese la dirección a la ruta /users/{id} con la identificación del usuario que desea eliminar, por ejemplo: http://localhost:4000/users/1
  4. Haga clic en el botón Send, debería recibir un "200 OK" respuesta con el mensaje "User deleted" en el cuerpo de la respuesta.

Esta es una captura de pantalla de Postman después de enviar la solicitud y eliminar al usuario:

Volver al principio


Ejecute una aplicación Angular con la API .NET CRUD

Para obtener detalles completos sobre la aplicación Angular CRUD, consulte la publicación Angular 11 - CRUD Example with Reactive Forms. Pero para ponerse en marcha rápidamente, solo siga los pasos a continuación.

  1. Instalar Node.js y npm desde https://nodejs.org.
  2. Descargue o clone el código del tutorial de Angular desde https://github.com/cornflourblue/angular-11-crud-example
  3. Instale todos los paquetes npm necesarios ejecutando npm install desde la línea de comando en la carpeta raíz del proyecto (donde se encuentra el package.json).
  4. Elimine o comente la línea debajo del comentario // provider used to create fake backend ubicado en el archivo /src/app/app.module.ts.
  5. Inicie la aplicación ejecutando npm start desde la línea de comando en la carpeta raíz del proyecto, esto iniciará un navegador que muestra la aplicación y debe estar conectado con la API CRUD de .NET 6 que usted ya se está ejecutando.


Ejecute una aplicación React con la API .NET CRUD

Para obtener detalles completos sobre la aplicación React CRUD, consulte la publicación React - CRUD Example with React Hook Form. Pero para ponerse en marcha rápidamente, solo siga los pasos a continuación.

  1. Instalar Node.js y npm desde https://nodejs.org.
  2. Descargue o clone el código del tutorial de React desde https://github.com/cornflourblue/react-hook-form-crud-example
  3. Instale todos los paquetes npm necesarios ejecutando npm install o npm i desde la línea de comando en la carpeta raíz del proyecto (donde se encuentra el package.json).
  4. Elimine o comente las 2 líneas debajo del comentario // setup fake backend ubicado en el archivo /src/index.jsx.
  5. Inicie la aplicación ejecutando npm start desde la línea de comando en la carpeta raíz del proyecto, esto iniciará un navegador que muestra la aplicación y debe estar conectado con la API CRUD de .NET 6 que usted ya se está ejecutando.


Estructura del proyecto API CRUD de .NET 6.0

El proyecto tutorial de .NET CRUD está organizado en las siguientes carpetas:

Controllers
Defina los puntos finales/rutas para la API web, los controladores son el punto de entrada a la API web desde las aplicaciones cliente a través de solicitudes http.

Models
Representa modelos de solicitud y respuesta para métodos de controlador, los modelos de solicitud definen parámetros para solicitudes entrantes y los modelos de respuesta definen datos personalizados que se devuelven en las respuestas cuando es necesario. El ejemplo solo contiene modelos request porque no contiene ninguna ruta que requiera modelos de respuesta personalizados, las rutas GET del usuario devuelven directamente las entidades.

Services
Contiene lógica empresarial, validación y código de acceso a la base de datos.

Entities
Representa los datos de la aplicación que se almacenan en la base de datos.
Entity Framework Core (EF Core) asigna datos relacionales de la base de datos a instancias de objetos de entidad de C# que se utilizarán dentro de la aplicación para la gestión de datos y las operaciones CRUD.

Helpers
Cualquier cosa que no encaje en las carpetas anteriores.

Haga clic en cualquiera de los enlaces a continuación para saltar a una descripción de cada archivo junto con su código:

 

Controlador de usuarios

Ruta: /Controllers/UsersController.cs

El controlador de usuarios de .NET define y maneja todas las rutas/puntos finales para la API que se relacionan con los usuarios, esto incluye operaciones CRUD estándar para recuperar, actualizar, crear y eliminar usuarios. Dentro de cada ruta, el controlador llama al servicio de usuario para realizar la acción requerida, lo que permite que el controlador permanezca 'esbelto' y completamente separado de la lógica y los datos comerciales. código de acceso.

namespace WebApi.Controllers;

using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using WebApi.Models.Users;
using WebApi.Services;

[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
    private IUserService _userService;
    private IMapper _mapper;

    public UsersController(
        IUserService userService,
        IMapper mapper)
    {
        _userService = userService;
        _mapper = mapper;
    }

    [HttpGet]
    public IActionResult GetAll()
    {
        var users = _userService.GetAll();
        return Ok(users);
    }

    [HttpGet("{id}")]
    public IActionResult GetById(int id)
    {
        var user = _userService.GetById(id);
        return Ok(user);
    }

    [HttpPost]
    public IActionResult Create(CreateRequest model)
    {
        _userService.Create(model);
        return Ok(new { message = "User created" });
    }

    [HttpPut("{id}")]
    public IActionResult Update(int id, UpdateRequest model)
    {
        _userService.Update(id, model);
        return Ok(new { message = "User updated" });
    }

    [HttpDelete("{id}")]
    public IActionResult Delete(int id)
    {
        _userService.Delete(id);
        return Ok(new { message = "User deleted" });
    }
}
 

Enumeración de funciones

Ruta: /Entities/Role.cs

La enumeración de funciones define todas las funciones disponibles en la API de ejemplo. Lo creé para evitar pasar roles como cadenas, así que en lugar de 'Admin' podemos usar Role.Admin.

namespace WebApi.Entities;

public enum Role
{
    Admin,
    User
}
 

Entidad de usuario

Ruta: /Entities/User.cs

La clase de entidad de usuario representa los datos almacenados en la base de datos para los usuarios.

Las clases de entidad también se usan para pasar datos entre diferentes partes de la aplicación (p. ej., entre servicios y controladores) y se pueden usar para devolver datos de respuesta http desde los métodos de acción del controlador.

El atributo [JsonIgnore] evita que la propiedad PasswordHash se serialice y se devuelva en las respuestas de la API.

Cuando se devuelve en las respuestas de la API, la propiedad de enumeración Role se serializa en una cadena (en lugar del número predeterminado) mediante el JsonStringEnumConverter() configurado en el Archivo Program.cs.

namespace WebApi.Entities;

using System.Text.Json.Serialization;

public class User
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public Role Role { get; set; }

    [JsonIgnore]
    public string PasswordHash { get; set; }
}
 

Excepción de la aplicación

Ruta: /Helpers/AppException.cs

La excepción de aplicación es una clase de excepción personalizada que se utiliza para diferenciar entre excepciones controladas y no controladas en la API de .NET. Las excepciones controladas son generadas por el código de la aplicación y se utilizan para devolver mensajes de error amigables, por ejemplo, excepciones de lógica de negocios o validación causadas por parámetros de solicitud no válidos, mientras que las excepciones no controladas son generadas por el marco .NET o causadas por errores en el código de la aplicación.

namespace WebApi.Helpers;

using System.Globalization;

// custom exception class for throwing application specific exceptions (e.g. for validation) 
// that can be caught and handled within the application
public class AppException : Exception
{
    public AppException() : base() {}

    public AppException(string message) : base(message) { }

    public AppException(string message, params object[] args) 
        : base(String.Format(CultureInfo.CurrentCulture, message, args))
    {
    }
}
 

Perfil de AutoMapper

Ruta: /Helpers/AutoMapperProfile.cs

El perfil de automapper contiene la configuración de mapeo utilizada por la aplicación, AutoMapper es un paquete disponible en Nuget que permite el mapeo automático entre diferentes tipos de C#. En este ejemplo, lo estamos usando para mapear entre entidades User y un par de tipos de modelos diferentes: CreateRequest y UpdateRequest.

namespace WebApi.Helpers;

using AutoMapper;
using WebApi.Entities;
using WebApi.Models.Users;

public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        // CreateRequest -> User
        CreateMap<CreateRequest, User>();

        // UpdateRequest -> User
        CreateMap<UpdateRequest, User>()
            .ForAllMembers(x => x.Condition(
                (src, dest, prop) =>
                {
                    // ignore both null & empty string properties
                    if (prop == null) return false;
                    if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;

                    // ignore null role
                    if (x.DestinationMember.Name == "Role" && src.Role == null) return false;

                    return true;
                }
            ));
    }
}
 

Contexto de datos

Ruta: /Helpers/DataContext.cs

La clase de contexto de datos se utiliza para acceder a los datos de la aplicación a través de Entity Framework. Se deriva de la clase DbContext de Entity Framework y tiene una propiedad Users pública para acceder y administrar los datos de los usuarios. El contexto de datos es utilizado por el servicio de usuario para manejar todas las operaciones de datos de bajo nivel (CRUD).

options.UseInMemoryDatabase() configura Entity Framework para crear y conectarse a una base de datos en memoria para que la API se pueda probar sin una base de datos real, esto se puede actualizar fácilmente para conectarse a una base de datos real servidor como SQL Server, Oracle, MySQL, etc. Para obtener instrucciones sobre cómo conectarlo a una base de datos de SQL Server, consulte .NET 5.0 - Connect to SQL Server with Entity Framework Core, para MySQL consulte .NET 5.0 - Connect to MySQL Database with Entity Framework Core.

namespace WebApi.Helpers;

using Microsoft.EntityFrameworkCore;
using WebApi.Entities;

public class DataContext : DbContext
{
    protected readonly IConfiguration Configuration;

    public DataContext(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        // in memory database used for simplicity, change to a real db for production applications
        options.UseInMemoryDatabase("TestDb");
    }

    public DbSet<User> Users { get; set; }
}
 

Middleware del controlador de errores globales

Ruta: /Helpers/ErrorHandlerMiddleware.cs

El controlador de errores global se utiliza para capturar todos los errores y eliminar la necesidad de un código de manejo de errores duplicado en toda la API de .NET. Está configurado como middleware en el archivo Program.cs.

Los errores de tipo AppException se tratan como errores personalizados (específicos de la aplicación) que devuelven una respuesta 400 Bad Request, la clase KeyNotFoundException incorporada de .NET se usa para devolver respuestas 404 Not Found, todas las demás excepciones no se manejan y devuelven una respuesta 500 Internal Server Error además de registrarse en la consola.

Consulte el servicio de usuario para ver ejemplos de errores personalizados y errores no encontrados generados por la API.

namespace WebApi.Helpers;

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text.Json;
using System.Threading.Tasks;

public class ErrorHandlerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public ErrorHandlerMiddleware(RequestDelegate next, ILogger<ErrorHandlerMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception error)
        {
            var response = context.Response;
            response.ContentType = "application/json";

            switch (error)
            {
                case AppException e:
                    // custom application error
                    response.StatusCode = (int)HttpStatusCode.BadRequest;
                    break;
                case KeyNotFoundException e:
                    // not found error
                    response.StatusCode = (int)HttpStatusCode.NotFound;
                    break;
                default:
                    // unhandled error
                    _logger.LogError(error, error.Message);
                    response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    break;
            }

            var result = JsonSerializer.Serialize(new { message = error?.Message });
            await response.WriteAsync(result);
        }
    }
}
 

Modelo de solicitud de creación

Ruta: /Models/Users/CreateRequest.cs

El modelo de solicitud de creación define los parámetros para las solicitudes POST entrantes a la ruta /users, se adjunta a la ruta configurándola como el parámetro de la acción Crear método del controlador de usuarios. Cuando la ruta recibe una solicitud HTTP POST, los datos del cuerpo se vinculan a una instancia de la clase CreateRequest, se validan y se pasan al método.

Las anotaciones de datos .NET se utilizan para manejar automáticamente la validación del modelo, [Required] hace que todas las propiedades sean obligatorias, [EmailAddress] valida que la propiedad de correo electrónico contenga una dirección de correo electrónico válida , [EnumDataType(typeof(Role))] valida que la propiedad del rol coincida con uno de los roles de API (administrador o usuario), [MinLength(6)] valida que el la contraseña contiene al menos seis caracteres, y [Compare("Password")] valida que la propiedad de confirmación de contraseña coincida con la propiedad de contraseña.

namespace WebApi.Models.Users;

using System.ComponentModel.DataAnnotations;
using WebApi.Entities;

public class CreateRequest
{
    [Required]
    public string Title { get; set; }

    [Required]
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    [Required]
    [EnumDataType(typeof(Role))]
    public string Role { get; set; }

    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    [MinLength(6)]
    public string Password { get; set; }

    [Required]
    [Compare("Password")]
    public string ConfirmPassword { get; set; }
}
 

Modelo de solicitud de actualización

Ruta: /Models/Users/UpdateRequest.cs

El modelo de solicitud de actualización define los parámetros para las solicitudes PUT entrantes a la ruta /users/{id}, se adjunta a la ruta configurándola como el parámetro para Update método de acción del controlador de usuarios. Cuando la ruta recibe una solicitud HTTP PUT, los datos del cuerpo se vinculan a una instancia de la clase UpdateRequest, se validan y pasan al método.

Las anotaciones de datos .NET se utilizan para manejar automáticamente la validación del modelo, [EnumDataType(typeof(Role))] valida que la propiedad del rol coincida con uno de los roles de la API (administrador o usuario), [EmailAddress] valida que la propiedad de correo electrónico contiene una dirección de correo electrónico válida, [MinLength(6)] valida que la contraseña contiene al menos seis caracteres y [Compare("Password")] valida que la propiedad de confirmación de contraseña coincida con la propiedad de contraseña.

Ninguna de las propiedades tiene el atributo [Required], lo que las convierte en opcionales, y los campos omitidos no se actualizan en la base de datos.

Algunos atributos de validación no manejan bien las cadenas vacías, las propiedades de la contraseña reemplazan las cadenas vacías con null en set para garantizar que se ignoren las cadenas vacías, porque los campos de contraseña son opcional en el formulario de actualización de usuario en las aplicaciones cliente Angular y React de ejemplo.

namespace WebApi.Models.Users;

using System.ComponentModel.DataAnnotations;
using WebApi.Entities;

public class UpdateRequest
{
    public string Title { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [EnumDataType(typeof(Role))]
    public string Role { get; set; }

    [EmailAddress]
    public string Email { get; set; }

    // treat empty string as null for password fields to 
    // make them optional in front end apps
    private string _password;
    [MinLength(6)]
    public string Password
    {
        get => _password;
        set => _password = replaceEmptyWithNull(value);
    }

    private string _confirmPassword;
    [Compare("Password")]
    public string ConfirmPassword 
    {
        get => _confirmPassword;
        set => _confirmPassword = replaceEmptyWithNull(value);
    }

    // helpers

    private string replaceEmptyWithNull(string value)
    {
        // replace empty string with null to make field optional
        return string.IsNullOrEmpty(value) ? null : value;
    }
}
 

Servicio de Usuario

Ruta: /Services/UserService.cs

El servicio de usuario es responsable de toda la interacción de la base de datos y la lógica comercial central relacionada con las operaciones CRUD del usuario.

La parte superior del archivo contiene una interfaz que define el servicio de usuario, justo debajo está la clase de servicio de usuario concreta que implementa la interfaz. BCrypt se usa para codificar y verificar contraseñas, para obtener más información, consulte .NET 6.0 - Hash and Verify Passwords with BCrypt.

namespace WebApi.Services;

using AutoMapper;
using BCrypt.Net;
using WebApi.Entities;
using WebApi.Helpers;
using WebApi.Models.Users;

public interface IUserService
{
    IEnumerable<User> GetAll();
    User GetById(int id);
    void Create(CreateRequest model);
    void Update(int id, UpdateRequest model);
    void Delete(int id);
}

public class UserService : IUserService
{
    private DataContext _context;
    private readonly IMapper _mapper;

    public UserService(
        DataContext context,
        IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    public IEnumerable<User> GetAll()
    {
        return _context.Users;
    }

    public User GetById(int id)
    {
        return getUser(id);
    }

    public void Create(CreateRequest model)
    {
        // validate
        if (_context.Users.Any(x => x.Email == model.Email))
            throw new AppException("User with the email '" + model.Email + "' already exists");

        // map model to new user object
        var user = _mapper.Map<User>(model);

        // hash password
        user.PasswordHash = BCrypt.HashPassword(model.Password);

        // save user
        _context.Users.Add(user);
        _context.SaveChanges();
    }

    public void Update(int id, UpdateRequest model)
    {
        var user = getUser(id);

        // validate
        if (model.Email != user.Email && _context.Users.Any(x => x.Email == model.Email))
            throw new AppException("User with the email '" + model.Email + "' already exists");

        // hash password if it was entered
        if (!string.IsNullOrEmpty(model.Password))
            user.PasswordHash = BCrypt.HashPassword(model.Password);

        // copy model to user and save
        _mapper.Map(model, user);
        _context.Users.Update(user);
        _context.SaveChanges();
    }

    public void Delete(int id)
    {
        var user = getUser(id);
        _context.Users.Remove(user);
        _context.SaveChanges();
    }

    // helper methods

    private User getUser(int id)
    {
        var user = _context.Users.Find(id);
        if (user == null) throw new KeyNotFoundException("User not found");
        return user;
    }
}
 

Configuración de la aplicación .NET 6 JSON

Ruta: /appsettings.json

El archivo appsettings.json es el archivo de configuración base en una aplicación .NET que contiene configuraciones para todos los entornos (p. ej., Development, Production ). Puede anular valores para diferentes entornos mediante la creación de archivos appsettings específicos del entorno (p. ej., appsettings.Development.json, appsettings.Production.json).

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft.AspNetCore": "Warning"
        }
    }
}
 

Programa .NET 6

Ruta: /Program.cs

El archivo de programa .NET 6 contiene top-level statements que el nuevo compilador C# 10 convierte en un método y clase Main() para el programa .NET . El método Main() es el punto de entrada para una aplicación .NET, cuando se inicia una aplicación busca el método Main() para comenzar la ejecución. Las top-level statements se pueden ubicar en cualquier parte del proyecto, pero generalmente se colocan en el archivo Program.cs, solo un archivo puede contener top-level statements dentro de una aplicación .NET.

La clase WebApplication maneja el inicio de la aplicación, la administración de por vida, la configuración del servidor web y más. Primero se crea un WebApplicationBuilder llamando al método estático WebApplication.CreateBuilder(args), el constructor se usa para configurar servicios para inyección de dependencia (DI), se crea una instancia de WebApplication llamando a builder.Build(), la instancia de la aplicación se usa para configurar la tubería de solicitud HTTP (middleware), luego la aplicación se inicia llamando a app.Run().

Envolví las secciones add services... y configure HTTP... entre llaves {} para agruparlas visualmente, los corchetes son completamente opcionales.

Internamente, la clase WebApplicationBuilder llama al método de extensión ConfigureWebHostDefaults() que configura el alojamiento para la aplicación web, incluida la configuración de Kestrel como servidor web, la adición de middleware de filtrado de host y la habilitación de IIS integración. Para obtener más información sobre la configuración predeterminada del generador, consulte https://docs.microsoft.com/aspnet/core/fundamentals/host/generic-host#default-builder-settings.

using System.Text.Json.Serialization;
using WebApi.Helpers;
using WebApi.Services;

var builder = WebApplication.CreateBuilder(args);

// add services to DI container
{
    var services = builder.Services;
    var env = builder.Environment;
 
    services.AddDbContext<DataContext>();
    services.AddCors();
    services.AddControllers().AddJsonOptions(x =>
    {
        // serialize enums as strings in api responses (e.g. Role)
        x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());

        // ignore omitted parameters on models to enable optional params (e.g. User update)
        x.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
    });
    services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

    // configure DI for application services
    services.AddScoped<IUserService, UserService>();
}

var app = builder.Build();

// configure HTTP request pipeline
{
    // global cors policy
    app.UseCors(x => x
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader());

    // global error handler
    app.UseMiddleware<ErrorHandlerMiddleware>();

    app.MapControllers();
}

app.Run("http://localhost:4000");
 

Archivo .NET 6 CSProj

Ruta: /WebApi.csproj

El csproj (proyecto C#) es un archivo basado en MSBuild que contiene el marco de destino y la información de dependencia del paquete NuGet para la aplicación. La función ImplicitUsings está habilitada, lo que le dice al compilador que genere automáticamente un conjunto de directivas de uso globales basadas en el tipo de proyecto, eliminando la necesidad de incluir muchas declaraciones de uso comunes en cada archivo de clase. Las instrucciones de uso global se generan automáticamente cuando crea el proyecto y se pueden encontrar en el archivo /obj/Debug/net6.0/WebApi.GlobalUsings.g.cs.

Para obtener más información sobre el archivo de proyecto de C#, consulte .NET + MSBuild - C# Project File (.csproj) in a Nutshell.

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="AutoMapper" Version="11.0.1" />
        <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
        <PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.3" />
    </ItemGroup>
</Project>

 


Suscríbete o Sígueme para actualizaciones

Suscríbete a mi canal de YouTube o sígueme en Twitter, Facebook o GitHub para recibir notificaciones cuando publique contenido nuevo.

Aparte de la codificación...

Actualmente estoy intentando viajar por Australia en motocicleta con mi esposa Tina en un par de Royal Enfield Himalayan. Puedes seguir nuestras aventuras en YouTube, Instagram y Facebook.


¿Necesita Ayuda .NET?

Buscar fiverr para encontrar ayuda rápidamente de desarrolladores .NET experimentados.