Partilhar via


Migrar da API Web do ASP.NET para o ASP.NET Core

O ASP.NET Core combina os modelos de aplicativo de API Web e MVC do ASP.NET 4.x em um único modelo de programação conhecido como ASP.NET Core MVC.

Esse artigo mostra como você pode migrar o controlador de Produtos criado em Introdução ao ASP.NET Web API 2 para o ASP.NET Core.

Pré-requisitos

Crie um projeto de API Web do ASP.NET Core

  1. No menu Arquivo, selecione Novo>Projeto.
  2. Insira API Web na caixa de pesquisa.
  3. Selecione o modelo API Web do ASP.NET Core e Avançar.
  4. Na caixa de diálogo Configurar seu novo projeto, nomeie o projeto como ProductsCore e selecione Avançar.
  5. Na caixa de diálogo Informações adicionais:
    1. Confirme se o Framework é o .NET 6.0 (suporte de longo prazo).
    2. Confirme se a caixa de seleção para Usar controladores (desmarcar para usar APIs mínimas) está marcada.
    3. Desmarque Habilitar suporte a OpenAPI.
    4. Selecione Criar.

Remova os arquivos de modelo WeatherForecast

  1. Remova os arquivos do exemplo WeatherForecast.cs e Controllers/WeatherForecastController.cs do novo projeto ProductsCore.
  2. Abra Properties\launchSettings.json.
  3. Altere as propriedades launchUrl de weatherforcast para productscore.

A configuração da API Web do ASP.NET Core

O ASP.NET Core não usa a pasta App_Start nem o arquivo Global.asax. O arquivo web.config é adicionado no momento da publicação. Para obter mais informações, consulte web.config file.

O arquivo Program.cs:

  • Substitui o arquivo Global.asax.
  • Trata de todas as tarefas de inicialização do aplicativo.

Saiba mais em Inicialização de aplicativos no ASP.NET Core.

A seguir, você verá o código de inicialização do aplicativo no arquivo 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();

Copie o modelo Produto

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no nome do projeto. Selecione Adicionar>Nova Pasta. Nomeie a pasta Models.
  2. Clique com o botão direito do mouse na pasta Modelos. Selecione Adicionar>Classe. Nomeie a classe Produto e selecione Adicionar.
  3. Substitua o código do modelo de template pelo seguinte:
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; }
    }
}

O código destacado anterior é alterado para o seguinte:

  • A anotação ? foi adicionada para declarar as propriedades Name e Category como tipos de referência anuláveis.

Ao utilizar o recurso Anulável introduzido no C# 8, o ASP.NET Core pode fornecer uma análise de fluxo de código adicional e segurança de tempo de compilação no tratamento de tipos de referência. Por exemplo, a proteção contra exceções de referência null.

Nesse caso, a intenção é que Name e Category possam ser tipos anuláveis.

Os projetos do ASP.NET Core 6.0 permitem tipos de referência anuláveis por padrão. Para obter mais informações, confira Tipos de referência anuláveis.

Copie o ProductsController

  1. Clique com o botão direito do mouse na pasta Controllers.
  2. Selecione Adicionar > Controlador....
  3. Na caixa de diálogo Adicionar Novo Item com Scaffold, selecione Controlador Mvc - Vazio e, em seguida, Adicionar.
  4. Nomeie o controlador como ProductsController e selecione Adicionar.
  5. Substitua o código do controlador do modelo pelo seguinte:
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;
    }
}

O código destacado anterior altera o seguinte, para que você migre para o ASP.NET Core:

  • Remove as instruções de uso dos seguintes componentes do ASP.NET 4.x que não existem no ASP.NET Core:

    • Classe ApiController
    • Namespace System.Web.Http
    • Interface IHttpActionResult
  • Altera a instrução using ProductsApp.Models; para using ProductsCore.Models;.

  • Define o namespace raiz como ProductsCore.

  • Altera ApiController para ControllerBase.

  • Adiciona using Microsoft.AspNetCore.Mvc; para resolver a referência ControllerBase.

  • Altera o tipo de retorno da ação GetProduct de IHttpActionResult para ActionResult<Product>. Para obter mais informações, consulte Tipos de retorno da ação do controlador.

  • Simplifica a instrução return da ação GetProduct para a seguinte instrução:

    return product;
    
  • Adiciona os seguintes atributos, que serão explicados nas próximas seções:

    • [Route("api/[controller]")]
    • [ApiController]
    • [HttpGet]
    • [HttpGet("{id}")]

Roteamento

O ASP.NET Core fornece um modelo de hospedagem mínimo no qual o middleware de roteamento de pontos de extremidade encapsula todo o pipeline de middleware, portanto, as rotas podem ser adicionadas diretamente ao WebApplication sem uma chamada explícita para UseEndpoints ou UseRouting para registrar rotas.

UseRouting ainda pode ser usado para especificar em que local ocorre a correspondência de rotas, mas UseRouting não precisa ser chamado explicitamente se as rotas devem ser correspondidas no início do pipeline do 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();

Observação: As rotas adicionadas diretamente ao WebApplication são executadas no fim do pipeline.

Roteamento no ProductsController migrado

O ProductsController migrado contém os seguintes atributos destacados:

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;
    }
}
  • O atributo [Route]configura o padrão de roteamento de atributos do controlador.

  • O atributo [ApiController] torna o roteamento de atributos um requisito para todas as ações nesse controlador.

  • O roteamento de atributos suporta tokens, como [controller] e [action]. No runtime, cada token é substituído pelo nome do controlador ou da ação, respectivamente, para o qual o atributo foi aplicado. Os tokens:

    • Reduzem ou eliminam a necessidade de você usar cadeias de caracteres codificadas para a rota.
    • Certifique-se de que as rotas permaneçam sincronizadas com os controladores e ações correspondentes quando as refatorações de renomeação automática forem aplicadas.
  • As solicitações HTTP Get são habilitadas para ações ProductController com os seguintes atributos:

    • [HttpGet] atributo aplicado à ação GetAllProducts.
    • [HttpGet("{id}")] atributo aplicado à ação GetProduct.

Execute o projeto migrado e navegue até /api/products. Por exemplo: https://localhost:<port>/api/produtos. Você verá uma lista completa de três produtos. Navegue até /api/products/1. O primeiro produto aparece.

Exibir ou baixar código de exemplo (como baixar)

Recursos adicionais

Esse artigo demonstra as etapas necessárias para migrar da API Web do ASP.NET 4.x para o ASP.NET Core MVC.

Exibir ou baixar código de exemplo (como baixar)

Pré-requisitos

Analise do projeto de API Web do ASP.NET 4.x

Esse artigo usa o projeto ProductsApp criado em Introdução ao ASP.NET Web API 2. Nesse projeto, um projeto básico de API da Web do ASP.NET 4.x é configurado da seguinte forma.

Em Global.asax.cs, é feita uma chamada para 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);
        }
    }
}

A classe WebApiConfig encontra-se na pasta App_Start e tem um 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 }
            );
        }
    }
}

A classe anterior:

  • Configura o roteamento do atributo, embora ele não esteja sendo usado de fato.
  • Configura a tabela de roteamento. O código de exemplo espera que as URLs correspondam ao formato /api/{controller}/{id}, sendo {id} opcional.

As seções a seguir demonstram a migração do projeto de API da Web para o ASP.NET Core MVC.

Criar o projeto de destino

Crie uma nova solução em branco no Visual Studio e adicione o projeto de API Web do ASP.NET 4.x que você deseja migrar:

  1. No menu Arquivo, selecione Novo>Projeto.
  2. Selecione o modelo Solução em Branco e selecione Avançar.
  3. Nomeie a solução como WebAPIMigration. Selecione Criar.
  4. Adicione o projeto ProductsApp existente à solução.

Adicione um novo projeto de API para o qual você deseja migrar:

  1. Adicione um novo projeto ASP.NET Core Web Application à solução.
  2. Na caixa de diálogo Configure seu novo projeto, nomeie o projeto ProductsCore e selecione Criar.
  3. Na caixa de diálogo Criar um aplicativo Web ASP.NET Core, confirme se .NET Core e ASP.NET Core 3.1 estão selecionados. Selecione o modelo de projeto API e, em seguida, Criar.
  4. Remova os arquivos do exemplo WeatherForecast.cs e Controllers/WeatherForecastController.cs do novo projeto ProductsCore.

A solução agora contém dois projetos. As seções a seguir explicam a migração do conteúdo do projeto ProductsApp para o projeto ProductsCore.

Migrar configuração

O ASP.NET Core não usa a pasta App_Start nem o arquivo Global.asax. Além disso, o arquivo web.config é adicionado no momento da publicação.

A classe Startup:

  • Substitui o arquivo Global.asax.
  • Trata de todas as tarefas de inicialização do aplicativo.

Saiba mais em Inicialização de aplicativos no ASP.NET Core.

Migrar modelos e controladores

O código a seguir mostra o ProductsController que deve ser atualizado para o 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);
        }
    }
}

Atualize o ProductsController para o ASP.NET Core:

  1. Copie Controllers/ProductsController.cs e a pasta Modelos do projeto original para o novo.
  2. Altere o namespace raiz dos arquivos copiados para ProductsCore.
  3. Atualize a declaração using ProductsApp.Models; para using ProductsCore.Models;.

Os seguintes componentes não existem no ASP.NET Core:

  • Classe ApiController
  • Namespace System.Web.Http
  • Interface IHttpActionResult

Faça as seguintes alterações:

  1. Alterar ApiController para ControllerBase. Adicione using Microsoft.AspNetCore.Mvc; para resolver a referência ControllerBase.

  2. Excluir using System.Web.Http;.

  3. Altere o tipo de retorno da ação GetProduct de IHttpActionResult para ActionResult<Product>.

  4. Simplifique a instrução return da ação GetProduct para o seguinte:

    return product;
    

Configurar o roteamento

O modelo de projeto de API ASP.NET Core inclui a configuração de roteamento de pontos de extremidade no código gerado.

As seguintes chamadas UseRouting e UseEndpoints:

  • Registre a correspondência de rota e a execução do ponto de extremidade no pipeline middleware.
  • Substitua o arquivo App_Start/WebApiConfig.cs do projeto 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 o roteamento da seguinte forma:

  1. Marque a classe ProductsController com os seguintes atributos:

    [Route("api/[controller]")]
    [ApiController]
    

    O atributo [Route] anterior configura o padrão de roteamento de atributos do controlador. O atributo [ApiController] torna o roteamento de atributos um requisito para todas as ações nesse controlador.

    O roteamento de atributos suporta tokens, como [controller] e [action]. No runtime, cada token é substituído pelo nome do controlador ou da ação, respectivamente, para o qual o atributo foi aplicado. Os tokens:

    • Reduzem o número de cadeias de caracteres mágicas no projeto.
    • Certifique-se de que as rotas permaneçam sincronizadas com os controladores e ações correspondentes quando as refatorações de renomeação automática forem aplicadas.
  2. Habilitar solicitações HTTP Get para as ações ProductsController:

    • Aplicar o atributo [HttpGet] à ação GetAllProducts.
    • Aplicar o atributo [HttpGet("{id}")] à ação GetProduct.

Execute o projeto migrado e navegue até /api/products. Você verá uma lista completa de três produtos. Navegue até /api/products/1. O primeiro produto aparece.

Recursos adicionais