Eseguire la migrazione da API Web ASP.NET a ASP.NET CoreMigrate from ASP.NET Web API to ASP.NET Core

Di Scott Addie e Steve SmithBy Scott Addie and Steve Smith

Un'API Web ASP.NET 4. x è un servizio HTTP che raggiunge un'ampia gamma di client, inclusi browser e dispositivi mobili.An ASP.NET 4.x Web API is an HTTP service that reaches a broad range of clients, including browsers and mobile devices. ASP.NET Core unifica i modelli di app per le API Web e MVC di ASP.NET 4. x in un modello di programmazione più semplice noto come ASP.NET Core MVC.ASP.NET Core unifies ASP.NET 4.x's MVC and Web API app models into a simpler programming model known as ASP.NET Core MVC. Questo articolo illustra i passaggi necessari per eseguire la migrazione dall'API Web ASP.NET 4. x a ASP.NET Core MVC.This article demonstrates the steps required to migrate from ASP.NET 4.x Web API to ASP.NET Core MVC.

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

PrerequisitesPrerequisites

Avviso

Se si usa Visual Studio 2017, vedere dotnet/sdk issue #3124 per informazioni sulle versioni di .NET Core SDK che non funzionano con Visual Studio.If you use Visual Studio 2017, see dotnet/sdk issue #3124 for information about .NET Core SDK versions that don't work with Visual Studio.

Esaminare il progetto API Web ASP.NET 4. xReview ASP.NET 4.x Web API project

Come punto di partenza, in questo articolo viene usato il progetto ProductsApp creato in Introduzione con API Web ASP.NET 2.As a starting point, this article uses the ProductsApp project created in Getting Started with ASP.NET Web API 2. In tale progetto, un semplice progetto API Web ASP.NET 4. x viene configurato come segue.In that project, a simple ASP.NET 4.x Web API project is configured as follows.

In Global.asax.csviene effettuata una chiamata a WebApiConfig.Register:In Global.asax.cs, a call is made to 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 classe WebApiConfig si trova nella cartella app_start e dispone di un metodo di Register statico:The WebApiConfig class is found in the App_Start folder and has a static Register method:

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 }
            );
        }
    }
}

Questa classe configura il routing degli attributi, sebbene non sia effettivamente utilizzato nel progetto.This class configures attribute routing, although it's not actually being used in the project. Viene inoltre configurata la tabella di routing, che viene utilizzata da API Web ASP.NET.It also configures the routing table, which is used by ASP.NET Web API. In questo caso, l'API Web ASP.NET 4. x prevede che gli URL corrispondano al formato /api/{controller}/{id}, con {id} essere facoltativo.In this case, ASP.NET 4.x Web API expects URLs to match the format /api/{controller}/{id}, with {id} being optional.

Il progetto ProductsApp include un controller.The ProductsApp project includes one controller. Il controller eredita da ApiController e contiene due azioni:The controller inherits from ApiController and contains two actions:

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);
        }
    }
}

Il modello di Product usato da ProductsController è una classe semplice:The Product model used by ProductsController is a simple class:

namespace ProductsApp.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

Le sezioni seguenti illustrano la migrazione del progetto API Web a ASP.NET Core MVC.The following sections demonstrate migration of the Web API project to ASP.NET Core MVC.

Crea progetto di destinazioneCreate destination project

Completare i passaggi seguenti in Visual Studio:Complete the following steps in Visual Studio:

  • Passare a File > nuovo progetto > > altri tipi di progetto > soluzioni di Visual Studio.Go to File > New > Project > Other Project Types > Visual Studio Solutions. Selezionare soluzione vuotae denominare la soluzione WebAPIMigration.Select Blank Solution, and name the solution WebAPIMigration. Fare clic sul pulsante OK .Click the OK button.
  • Aggiungere il progetto ProductsApp esistente alla soluzione.Add the existing ProductsApp project to the solution.
  • Aggiungere un nuovo progetto di applicazione Web ASP.NET Core alla soluzione.Add a new ASP.NET Core Web Application project to the solution. Selezionare .NET Core Target Framework dall'elenco a discesa e selezionare il modello di progetto API .Select the .NET Core target framework from the drop-down, and select the API project template. Denominare il progetto ProductsCoree fare clic sul pulsante OK .Name the project ProductsCore, and click the OK button.

La soluzione ora contiene due progetti.The solution now contains two projects. Le sezioni seguenti illustrano come eseguire la migrazione del contenuto del progetto ProductsApp al progetto ProductsCore .The following sections explain migrating the ProductsApp project's contents to the ProductsCore project.

Esegui migrazione configurazioneMigrate configuration

ASP.NET Core non utilizza la cartella app_start o il file Global. asax e il file Web. config viene aggiunto in fase di pubblicazione.ASP.NET Core doesn't use the App_Start folder or the Global.asax file, and the web.config file is added at publish time. Startup.cs è la sostituzione di Global. asax e si trova nella radice del progetto.Startup.cs is the replacement for Global.asax and is located in the project root. La classe Startup gestisce tutte le attività di avvio dell'app.The Startup class handles all app startup tasks. Per altre informazioni, vedere Avvio dell'app in ASP.NET Core.For more information, see Avvio dell'app in ASP.NET Core.

In ASP.NET Core MVC, il routing degli attributi è incluso per impostazione predefinita quando viene chiamato UseMvc in Startup.Configure.In ASP.NET Core MVC, attribute routing is included by default when UseMvc is called in Startup.Configure. La chiamata di UseMvc seguente sostituisce il file di app_start/webapiconfig.cs del progetto ProductsApp :The following UseMvc call replaces the ProductsApp project's App_Start/WebApiConfig.cs file:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseMvc();
}

Eseguire la migrazione di modelli e controllerMigrate models and controllers

Copiare il controller del progetto ProductApp e il modello usato.Copy over the ProductApp project's controller and the model it uses. A tale scopo, seguire questa procedura:Follow these steps:

  1. Copiare Controllers/ProductsController. cs dal progetto originale a quello nuovo.Copy Controllers/ProductsController.cs from the original project to the new one.
  2. Copiare l'intera cartella Models dal progetto originale a quella nuova.Copy the entire Models folder from the original project to the new one.
  3. Modificare gli spazi dei nomi dei file copiati in modo che corrispondano al nuovo nome del progetto (ProductsCore).Change the copied files' namespaces to match the new project name (ProductsCore). Modificare anche l'istruzione using ProductsApp.Models; in ProductsController.cs .Adjust the using ProductsApp.Models; statement in ProductsController.cs too.

A questo punto, la compilazione dell'app comporta una serie di errori di compilazione.At this point, building the app results in a number of compilation errors. Gli errori si verificano perché i componenti seguenti non esistono in ASP.NET Core:The errors occur because the following components don't exist in ASP.NET Core:

  • Classe ApiControllerApiController class
  • Spazio dei nomi System.Web.HttpSystem.Web.Http namespace
  • interfaccia IHttpActionResultIHttpActionResult interface

Correggere gli errori nel modo seguente:Fix the errors as follows:

  1. Cambiare ApiController in ControllerBase.Change ApiController to ControllerBase. Aggiungere using Microsoft.AspNetCore.Mvc; per risolvere il riferimento ControllerBase.Add using Microsoft.AspNetCore.Mvc; to resolve the ControllerBase reference.
  2. Eliminare using System.Web.Http;.Delete using System.Web.Http;.
  3. Modificare il tipo restituito dell'azione di GetProduct da IHttpActionResult a ActionResult<Product>.Change the GetProduct action's return type from IHttpActionResult to ActionResult<Product>.

Semplificare l'istruzione return dell'azione GetProduct per quanto segue:Simplify the GetProduct action's return statement to the following:

return product;

Configurare il routingConfigure routing

Configurare il routing come segue:Configure routing as follows:

  1. Contrassegnare la classe ProductsController con gli attributi seguenti:Mark the ProductsController class with the following attributes:

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

    L'attributo [Route] precedente configura il modello di routing degli attributi del controller.The preceding [Route] attribute configures the controller's attribute routing pattern. L'attributo [ApiController] rende il routing degli attributi un requisito per tutte le azioni nel controller.The [ApiController] attribute makes attribute routing a requirement for all actions in this controller.

    Il routing degli attributi supporta i token, ad esempio [controller] e [action].Attribute routing supports tokens, such as [controller] and [action]. In fase di esecuzione, ogni token viene sostituito rispettivamente dal nome del controller o dell'azione a cui è stato applicato l'attributo.At runtime, each token is replaced with the name of the controller or action, respectively, to which the attribute has been applied. I token riducono il numero di stringhe magiche nel progetto.The tokens reduce the number of magic strings in the project. I token assicurano inoltre che le route rimangano sincronizzate con i controller e le azioni corrispondenti quando vengono applicati i refactoring di ridenominazione automatica.The tokens also ensure routes remain synchronized with the corresponding controllers and actions when automatic rename refactorings are applied.

  2. Impostare la modalità di compatibilità del progetto su ASP.NET Core 2,2:Set the project's compatibility mode to ASP.NET Core 2.2:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }
    

    La modifica precedente:The preceding change:

    • È necessario per usare l'attributo [ApiController] a livello di controller.Is required to use the [ApiController] attribute at the controller level.
    • Consente di optare per i comportamenti potenzialmente innovatori introdotti in ASP.NET Core 2,2.Opts in to potentially breaking behaviors introduced in ASP.NET Core 2.2.
  3. Abilitare le richieste HTTP Get alle azioni ProductController:Enable HTTP Get requests to the ProductController actions:

    • Applicare l'attributo [HttpGet] all'azione GetAllProducts.Apply the [HttpGet] attribute to the GetAllProducts action.
    • Applicare l'attributo [HttpGet("{id}")] all'azione GetProduct.Apply the [HttpGet("{id}")] attribute to the GetProduct action.

Dopo le modifiche precedenti e la rimozione delle istruzioni using inutilizzate, il file ProductsController.cs ha un aspetto simile al seguente:After the preceding changes and the removal of unused using statements, ProductsController.cs file looks like this:

using System.Collections.Generic;
using System.Linq;
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;
        }
    }
}

Eseguire il progetto migrato e passare a /api/products.Run the migrated project, and browse to /api/products. Viene visualizzato un elenco completo di tre prodotti.A full list of three products appears. Passare a /api/products/1.Browse to /api/products/1. Il primo prodotto verrà visualizzato.The first product appears.

Shim di compatibilitàCompatibility shim

La libreria Microsoft. AspNetCore. Mvc. WebApiCompatShim fornisce uno shim di compatibilità per spostare i progetti API Web ASP.NET 4. x in ASP.NET Core.The Microsoft.AspNetCore.Mvc.WebApiCompatShim library provides a compatibility shim to move ASP.NET 4.x Web API projects to ASP.NET Core. Lo shim di compatibilità estende ASP.NET Core per supportare una serie di convenzioni di ASP.NET 4. x Web API 2.The compatibility shim extends ASP.NET Core to support a number of conventions from ASP.NET 4.x Web API 2. L'esempio portato in precedenza in questo documento è abbastanza elementare che lo shim di compatibilità non fosse necessario.The sample ported previously in this document is basic enough that the compatibility shim was unnecessary. Per i progetti di grandi dimensioni, l'uso dello shim di compatibilità può essere utile per colmare temporaneamente il gap dell'API tra ASP.NET Core e ASP.NET 4. x Web API 2.For larger projects, using the compatibility shim can be useful for temporarily bridging the API gap between ASP.NET Core and ASP.NET 4.x Web API 2.

Lo shim di compatibilità dell'API Web è pensato per essere usato come misura temporanea per supportare la migrazione di progetti API Web ASP.NET 4. x di grandi dimensioni a ASP.NET Core.The Web API compatibility shim is meant to be used as a temporary measure to support migrating large ASP.NET 4.x Web API projects to ASP.NET Core. Nel corso del tempo, è necessario aggiornare i progetti in modo da usare ASP.NET Core modelli anziché basarsi sullo shim di compatibilità.Over time, projects should be updated to use ASP.NET Core patterns instead of relying on the compatibility shim.

Le funzionalità di compatibilità incluse in Microsoft.AspNetCore.Mvc.WebApiCompatShim includono:Compatibility features included in Microsoft.AspNetCore.Mvc.WebApiCompatShim include:

  • Aggiunge un tipo di ApiController in modo che i tipi di base dei controller non debbano essere aggiornati.Adds an ApiController type so that controllers' base types don't need to be updated.
  • Abilita l'associazione di modelli di tipo API Web.Enables Web API-style model binding. ASP.NET Core funzioni di associazione di modelli MVC in modo analogo a quello di ASP.NET 4. x MVC 5, per impostazione predefinita.ASP.NET Core MVC model binding functions similarly to that of ASP.NET 4.x MVC 5, by default. Lo shim di compatibilità modifica l'associazione di modelli in modo da essere più simile alle convenzioni di associazione del modello ASP.NET 4. x Web API 2.The compatibility shim changes model binding to be more similar to ASP.NET 4.x Web API 2 model binding conventions. Ad esempio, i tipi complessi vengono automaticamente associati dal corpo della richiesta.For example, complex types are automatically bound from the request body.
  • Estende l'associazione di modelli in modo che le azioni del controller possano prendere parametri di tipo HttpRequestMessage.Extends model binding so that controller actions can take parameters of type HttpRequestMessage.
  • Aggiunge formattatori di messaggi che consentono alle azioni di restituire risultati di tipo HttpResponseMessage.Adds message formatters allowing actions to return results of type HttpResponseMessage.
  • Aggiunge metodi di risposta aggiuntivi che possono essere usati dalle azioni API Web 2 per rispondere alle risposte:Adds additional response methods that Web API 2 actions may have used to serve responses:
    • generatori di HttpResponseMessage:HttpResponseMessage generators:
      • CreateResponse<T>
      • CreateErrorResponse
    • Metodi di risultato dell'azione:Action result methods:
      • BadRequestErrorMessageResult
      • ExceptionResult
      • InternalServerErrorResult
      • InvalidModelStateResult
      • NegotiatedContentResult
      • ResponseMessageResult
  • Aggiunge un'istanza di IContentNegotiator al contenitore DI inserimento delle dipendenze dell'app e rende disponibili i tipi correlati alla negoziazione del contenuto da Microsoft. AspNet. WebAPI. client.Adds an instance of IContentNegotiator to the app's dependency injection (DI) container and makes available the content negotiation-related types from Microsoft.AspNet.WebApi.Client. Esempi di tali tipi includono DefaultContentNegotiator e MediaTypeFormatter.Examples of such types include DefaultContentNegotiator and MediaTypeFormatter.

Per usare lo shim di compatibilità:To use the compatibility shim:

  1. Installare il pacchetto NuGet Microsoft. AspNetCore. Mvc. WebApiCompatShim .Install the Microsoft.AspNetCore.Mvc.WebApiCompatShim NuGet package.
  2. Registrare i servizi dello shim di compatibilità con il contenitore DI inserimento dell'app chiamando services.AddMvc().AddWebApiConventions() in Startup.ConfigureServices.Register the compatibility shim's services with the app's DI container by calling services.AddMvc().AddWebApiConventions() in Startup.ConfigureServices.
  3. Definire route specifiche dell'API Web usando MapWebApiRoute sul IRouteBuilder nella chiamata IApplicationBuilder.UseMvc dell'app.Define web API-specific routes using MapWebApiRoute on the IRouteBuilder in the app's IApplicationBuilder.UseMvc call.

Risorse aggiuntiveAdditional resources