Migración de ASP.NET Web API a ASP.NET Core
ASP.NET Core combina los modelos de aplicación MVC y Web API de ASP.NET 4.x en un único modelo de programación conocido como ASP.NET Core MVC.
En este artículo se muestra cómo migrar el controlador Products creado en Introducción con ASP.NET Web API 2 a ASP.NET Core.
Requisitos previos
- Visual Studio 2022 con la carga de trabajo de ASP.NET y desarrollo web
- SDK de .NET 6.0
Crear el nuevo proyecto ASP.NET Core Web API
- En el menú Archivo, seleccione Nuevo>Proyecto.
- Escriba API web en el cuadro de búsqueda.
- Seleccione la plantilla API web de ASP.NET Core y seleccione Siguiente.
- En el cuadro de diálogo Configure su nuevo proyecto, nombre el proyecto ProductsCore y seleccione Siguiente.
- En el cuadro de diálogo Información adicional:
- Confirme que el Marco es .NET 6.0 (Compatibilidad a largo plazo).
- Confirme que la casilla Use controllers(uncheck to use minimal APIs) [Usar controladores (desactivar para usar API mínimas)] está activada.
- Desactive Habilitar compatibilidad con OpenAPI.
- Seleccione Crear.
Elimine los archivos de plantilla WeatherForecast.
- Elimine los archivos de ejemplo
WeatherForecast.cs
yControllers/WeatherForecastController.cs
del nuevo proyecto ProductsCore. - Abra Properties\launchSettings.json.
- Cambie las propiedades de
launchUrl
deweatherforcast
aproductscore
.
La Configuración para ASP.NET Core Web API
ASP.NET Core no utiliza la carpeta App_Start ni el archivo Global.asax. El archivo web.config se añade en el momento de la publicación. Para más información, consulte archivo web.config.
El archivo Program.cs
:
- Sustituye a Global.asax.
- Maneja todas las tareas de inicio de la aplicación.
Para obtener más información, vea Inicio de la aplicación en ASP.NET Core.
A continuación se muestra el código de inicio de la aplicación en el archivo ASP.NET Core Program.cs
:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Copiar el modelo Producto
- En el Explorador de soluciones, haga clic con el botón derecho en el proyecto. Seleccione Agregar>Nueva carpeta. Asigne a la carpeta el nombre Models.
- Haga clic con el botón derecho en la carpeta Models. Seleccione Agregar>Clase. Nombre la clase Producto y seleccione Añadir.
- Sustituya el código del modelo de plantilla por lo siguiente:
namespace ProductsCore.Models
{
public class Product
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Category { get; set; }
public decimal Price { get; set; }
}
}
El código resaltado anterior cambia lo siguiente:
- Se ha añadido la anotación
?
para declarar las propiedadesName
yCategory
como tipos de referencia nula.
Al utilizar la función Nullable introducida en C# 8, ASP.NET Core puede proporcionar un análisis de flujo de código adicional y seguridad en tiempo de compilación en el manejo de tipos de referencia. Por ejemplo, protección frente a excepciones de referencia null
.
En este caso, la intención es que Name
y Category
puedan ser tipo que acepta valores NULL.
Los proyectos ASP.NET Core 6.0 permiten tipos de referencia nula de manera predeterminada. Para más información, consulte Tipos de referencia que admiten un valor NULL.
Copie el ProductsController
- Haga clic con el botón derecho en la carpeta Controllers.
- Seleccione Añadir > Controlador....
- En el cuadro de diálogo Agregar nuevo elemento de andamio, seleccione Controlador Mvc - Vacío y, a continuación, seleccione Agregar.
- Nombre el controlador ProductsController y seleccione Agregar.
- Sustituya el código del controlador de plantilla por el siguiente:
using Microsoft.AspNetCore.Mvc;
using ProductsCore.Models;
namespace ProductsCore.Controllers;
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
Product[] products = new Product[]
{
new Product
{
Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1
},
new Product
{
Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M
},
new Product
{
Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M
}
};
[HttpGet]
public IEnumerable<Product> GetAllProducts()
{
return products;
}
[HttpGet("{id}")]
public ActionResult<Product> GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return product;
}
}
El código resaltado anterior cambia lo siguiente, para migrar a ASP.NET Core:
Quita las sentencias con de los siguientes componentes de ASP.NET 4.x que no existen en ASP.NET Core:
- Clase
ApiController
- Espacio de nombres
System.Web.Http
IHttpActionResult
(interfaz)
- Clase
Cambia la sentencia
using ProductsApp.Models;
porusing ProductsCore.Models;
.Establece el espacio de nombres raíz en
ProductsCore
.Cambia
ApiController
por ControllerBase.Añade
using Microsoft.AspNetCore.Mvc;
para resolver la referenciaControllerBase
.Cambia el tipo de retorno de la acción
GetProduct
deIHttpActionResult
aActionResult<Product>
. Para obtener más información, consulte Tipos de valor devuelto de acción del controlador.Simplifica la sentencia
return
de la acciónGetProduct
a la siguiente sentencia:return product;
Añade los siguientes atributos que se explican en las siguientes secciones:
[Route("api/[controller]")]
[ApiController]
[HttpGet]
[HttpGet("{id}")]
Enrutamiento
ASP.NET Core proporciona un modelo de alojamiento mínimo en el que el middleware de enrutamiento de punto de conexión envuelve toda la canalización de middleware, por lo tanto, las rutas se pueden agregar directamente a la WebApplication sin una llamada explícita a UseEndpoints o UseRouting para registrar rutas.
UseRouting
todavía se puede usar para especificar dónde se produce la coincidencia de rutas, pero UseRouting
no es necesario llamar explícitamente si las rutas deben coincidir al principio de la canalización de middleware.
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Nota: Las rutas agregadas directamente a WebApplication se ejecutan al final de la canalización.
Enrutamiento en el ProductsController
migrado
El ProductsController
migrado contiene los siguientes atributos resaltados:
using Microsoft.AspNetCore.Mvc;
using ProductsCore.Models;
namespace ProductsCore.Controllers;
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
Product[] products = new Product[]
{
new Product
{
Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1
},
new Product
{
Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M
},
new Product
{
Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M
}
};
[HttpGet]
public IEnumerable<Product> GetAllProducts()
{
return products;
}
[HttpGet("{id}")]
public ActionResult<Product> GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return product;
}
}
El atributo
[Route]
configura el patrón de enrutamiento de atributos del controlador.El atributo
[ApiController]
hace que el enrutamiento de atributos sea un requisito para todas las acciones de este controlador.El enrutamiento de atributos admite tokens, como
[controller]
y[action]
. En tiempo de ejecución, cada token se sustituye por el nombre del controlador o acción, respectivamente, al que se ha aplicado el atributo. Los tokens:- Reducen o eliminan la necesidad de utilizar cadenas codificadas para la ruta.
- Garantizan que las rutas permanezcan sincronizadas con los controladores y acciones correspondientes cuando se aplican refactorizaciones automáticas de cambio de nombre.
Las peticiones HTTP Get están habilitadas para las acciones
ProductController
con los siguientes atributos:[HttpGet]
atributo aplicado a la acciónGetAllProducts
.[HttpGet("{id}")]
atributo aplicado a la acciónGetProduct
.
Ejecute el proyecto migrado y vaya a /api/products
. Por ejemplo: https://localhost:<port>
/api/products. Aparece una lista completa de tres productos. Vaya a /api/products/1
. Aparece el primer producto.
Vea o descargue el código de ejemplo (cómo descargarlo)
Recursos adicionales
En este artículo se muestran los pasos necesarios para migrar de ASP.NET API web 4.x a ASP.NET Core MVC.
Vea o descargue el código de ejemplo (cómo descargarlo)
Requisitos previos
- Versión 16.4 o posterior de Visual Studio 2019 con la carga de trabajo Desarrollo web y ASP.NET
- SDK de .NET Core 3.1
Revisión ASP.NET proyecto de API web 4.x
En este artículo se usa el proyecto ProductsApp creado en Introducción con ASP.NET Web API 2. En ese proyecto, se configura un proyecto de API web de ASP.NET 4.x básico como se indica a continuación.
En Global.asax.cs
, se realiza una llamada a WebApiConfig.Register
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Routing;
namespace ProductsApp
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
La clase WebApiConfig
se encuentra en la carpeta App_Start y tiene un método estático Register
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace ProductsApp
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
La clase anterior:
- Configura el enrutamiento de atributos, aunque realmente no se usa.
- Configura la tabla de enrutamiento.
El código de ejemplo espera que las URL coincidan con el formato
/api/{controller}/{id}
, siendo{id}
opcional.
Las siguientes secciones demuestran la migración del proyecto de API web a ASP.NET Core MVC.
Creación del proyecto de destino
Cree una nueva solución en blanco en Visual Studio y añada el proyecto ASP.NET 4.x Web API que desea migrar:
- En el menú Archivo, seleccione Nuevo>Proyecto.
- Seleccione la plantilla Solución en blanco y seleccione Siguiente.
- Nombre la solución WebAPIMigration. Seleccione Crear.
- Añada el proyecto ProductsApp existente a la solución.
Añada un nuevo proyecto API al que migrar:
- Añada un nuevo proyecto ASP.NET Core Web Application a la solución.
- En el cuadro de diálogo Configure su nuevo proyecto, nombre el proyecto ProductsCore y seleccione Crear.
- En el cuadro de diálogo Crear una aplicación web ASP.NET Core, confirme que las opciones .NET Core y ASP.NET Core 3.1 estén seleccionadas. Seleccione la plantilla de proyecto API y, luego, Crear.
- Elimine los archivos de ejemplo
WeatherForecast.cs
yControllers/WeatherForecastController.cs
del nuevo proyecto ProductsCore.
La solución contiene ahora dos proyectos. En las siguientes secciones se explica cómo migrar el contenido del proyecto ProductsApp al proyecto ProductsCore.
Migración de la configuración
ASP.NET Core no utiliza la carpeta App_Start ni el archivo Global.asax. Además, el archivo web.config se añade en el momento de la publicación.
La clase Startup
:
- Sustituye a Global.asax.
- Maneja todas las tareas de inicio de la aplicación.
Para obtener más información, vea Inicio de la aplicación en ASP.NET Core.
Migrar modelos y controladores
El siguiente código muestra el ProductsController
que debe actualizarse para ASP.NET Core:
using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
namespace ProductsApp.Controllers
{
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product
{
Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1
},
new Product
{
Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M
},
new Product
{
Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M
}
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public IHttpActionResult GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
}
Actualizar el ProductsController
para ASP.NET Core:
- Copie
Controllers/ProductsController.cs
y la carpeta Models del proyecto original al nuevo. - Cambie el espacio de nombres raíz de los archivos copiados a
ProductsCore
. - Actualice la declaración
using ProductsApp.Models;
ausing ProductsCore.Models;
.
Los siguientes componentes no existen en ASP.NET Core:
- Clase
ApiController
- Espacio de nombres
System.Web.Http
IHttpActionResult
(interfaz)
Realice los cambios siguientes:
Cambio de
ApiController
a ControllerBase. Añadausing Microsoft.AspNetCore.Mvc;
para resolver la referenciaControllerBase
.Elimine
using System.Web.Http;
.Cambiar el tipo de retorno de la acción
GetProduct
deIHttpActionResult
aActionResult<Product>
.Simplifique la declaración
return
de la acciónGetProduct
a lo siguiente:return product;
Configuración del enrutamiento
La plantilla de proyecto ASP.NET Core API incluye la configuración de enrutamiento de punto de conexión en el código generado.
Las siguientes llamadas UseRouting y UseEndpoints:
- Registrar la coincidencia de rutas y la ejecución de puntos de conexión en la canalización middleware.
- Sustituya el archivo
App_Start/WebApiConfig.cs
del proyecto ProductsApp.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Configure el enrutamiento como se indica a continuación:
Marque la clase
ProductsController
con los siguientes atributos:[Route("api/[controller]")] [ApiController]
El atributo
[Route]
anterior configura el patrón de enrutamiento de atributos del controlador. El atributo[ApiController]
hace que el enrutamiento de atributos sea un requisito para todas las acciones de este controlador.El enrutamiento de atributos admite tokens, como
[controller]
y[action]
. En tiempo de ejecución, cada token se sustituye por el nombre del controlador o acción, respectivamente, al que se ha aplicado el atributo. Los tokens:- Reduzca el número de cadenas mágicas del proyecto.
- Garantizan que las rutas permanezcan sincronizadas con los controladores y acciones correspondientes cuando se aplican refactorizaciones automáticas de cambio de nombre.
Habilitar peticiones HTTP Get a las acciones
ProductsController
:- Aplicar el atributo
[HttpGet]
a la acciónGetAllProducts
. - Aplicar el atributo
[HttpGet("{id}")]
a la acciónGetProduct
.
- Aplicar el atributo
Ejecute el proyecto migrado y vaya a /api/products
. Aparece una lista completa de tres productos. Vaya a /api/products/1
. Aparece el primer producto.