Nozioni fondamentali su ASP.NET CoreASP.NET Core fundamentals

Questo articolo contiene una panoramica degli argomenti chiave necessari per comprendere come sviluppare app ASP.NET Core.This article is an overview of key topics for understanding how to develop ASP.NET Core apps.

Classe StartupThe Startup class

All'interno della classe Startup:The Startup class is where:

  • Vengono configurati i servizi necessari per l'app.Services required by the app are configured.
  • Viene definita la pipeline di gestione delle richieste.The request handling pipeline is defined.

I servizi sono componenti usati dall'app.Services are components that are used by the app. Ad esempio, un componente di registrazione è un servizio.For example, a logging component is a service. Il codice per configurare o registrare i servizi viene aggiunto al metodo Startup.ConfigureServices.Code to configure (or register) services is added to the Startup.ConfigureServices method.

La pipeline di gestione delle richieste è strutturata come una serie di componenti middleware.The request handling pipeline is composed as a series of middleware components. Un componente middleware, ad esempio, potrebbe gestire le richieste per i file statici o reindirizzare le richieste HTTP a HTTPS.For example, a middleware might handle requests for static files or redirect HTTP requests to HTTPS. Ogni componente middleware esegue operazioni asincrone su un HttpContext, quindi richiama il componente middleware successivo della pipeline oppure termina la richiesta.Each middleware performs asynchronous operations on an HttpContext and then either invokes the next middleware in the pipeline or terminates the request. Il codice per configurare la pipeline di gestione delle richieste viene aggiunto al metodo Startup.Configure.Code to configure the request handling pipeline is added to the Startup.Configure method.

Ecco un esempio di classe Startup:Here's a sample Startup class:

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

        services.AddDbContext<MovieContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("MovieDb")));
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseMvc();
    }
}

Per ulteriori informazioni, vedere Avvio dell'app in ASP.NET Core.For more information, see Avvio dell'app in ASP.NET Core.

Iniezione di dipendenze (servizi)Dependency injection (services)

ASP.NET Core include un framework di inserimento delle dipendenze predefinito che rende disponibili i servizi configurati per le classi di un'app.ASP.NET Core has a built-in dependency injection (DI) framework that makes configured services available to an app's classes. Un modo per inserire un'istanza di un servizio in una classe consiste nel creare un costruttore con un parametro del tipo richiesto.One way to get an instance of a service in a class is to create a constructor with a parameter of the required type. Il parametro può essere il tipo di servizio o un'interfaccia.The parameter can be the service type or an interface. Il sistema di inserimento delle dipendenze fornisce il servizio in runtime.The DI system provides the service at runtime.

Di seguito viene proposto un esempio di classe che usa l'inserimento delle dipendenze per ottenere un oggetto di contesto Entity Framework Core.Here's a class that uses DI to get an Entity Framework Core context object. La riga evidenziata è un esempio di inserimento costruttore:The highlighted line is an example of constructor injection:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovieContext context)
    {
        _context = context;
    }
    // ...
    public async Task OnGetAsync()
    {
        var movies = from m in _context.Movies
                        select m;
        Movies = await movies.ToListAsync();
    }
}

Nonostante l'inserimento delle dipendenze sia predefinito, è progettato per consentire il collegamento di un contenitore di inversione del controllo (IoC) di terze parti, qualora lo si preferisse.While DI is built in, it's designed to let you plug in a third-party Inversion of Control (IoC) container if you prefer.

Per ulteriori informazioni, vedere Inserimento delle dipendenze in ASP.NET Core.For more information, see Inserimento delle dipendenze in ASP.NET Core.

MiddlewareMiddleware

La pipeline di gestione delle richieste è strutturata come una serie di componenti middleware.The request handling pipeline is composed as a series of middleware components. Ogni componente esegue operazioni asincrone su un HttpContext, quindi richiama il componente middleware successivo nella pipeline oppure termina la richiesta.Each component performs asynchronous operations on an HttpContext and then either invokes the next middleware in the pipeline or terminates the request.

Per convenzione viene aggiunto un componente middleware alla pipeline richiamando il relativo metodo di estensione Use... nel metodo Startup.Configure.By convention, a middleware component is added to the pipeline by invoking its Use... extension method in the Startup.Configure method. Per abilitare il rendering dei file statici, ad esempio, chiamare UseStaticFiles.For example, to enable rendering of static files, call UseStaticFiles.

Il codice evidenziato nell'esempio seguente configura la pipeline di gestione delle richieste:The highlighted code in the following example configures the request handling pipeline:

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

        services.AddDbContext<MovieContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("MovieDb")));
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseMvc();
    }
}

ASP.NET Core include un ampio set di middleware predefiniti, ma consente anche di scrivere middleware personalizzati.ASP.NET Core includes a rich set of built-in middleware, and you can write custom middleware.

Per ulteriori informazioni, vedere Middleware di ASP.NET Core.For more information, see Middleware di ASP.NET Core.

HostHost

Un'app ASP.NET Core crea un host all'avvio.An ASP.NET Core app builds a host on startup. L'host è un oggetto che incapsula tutte le risorse dell'app, ad esempio:The host is an object that encapsulates all of the app's resources, such as:

  • Un'implementazione del server HTTPAn HTTP server implementation
  • I componenti middlewareMiddleware components
  • RegistrazioneLogging
  • Inserimento delle dipendenzeDI
  • ConfigurazioneConfiguration

Il motivo principale per cui tutte le risorse interdipendenti dell'app sono incluse in un unico oggetto è la gestione del ciclo di vita, vale a dire il controllo sull'avvio dell'app e sull'arresto normale.The main reason for including all of the app's interdependent resources in one object is lifetime management: control over app startup and graceful shutdown.

Sono disponibili due host: l'host generico e l'host Web.Two hosts are available: the Generic Host and the Web Host. È consigliato l'uso dell'host generico, mentre l'host Web è disponibile solo per compatibilità con le versioni precedenti.The Generic Host is recommended, and the Web Host is available only for backwards compatibility.

Il codice per creare un host si trova in Program.Main:The code to create a host is in Program.Main:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

I metodi CreateDefaultBuilder e ConfigureWebHostDefaults configurano un host con le opzioni usate comunemente, ad esempio:The CreateDefaultBuilder and ConfigureWebHostDefaults methods configure a host with commonly used options, such as the following:

  • Usare Kestrel come server Web e abilitare l'integrazione IIS.Use Kestrel as the web server and enable IIS integration.
  • Caricare la configurazione da appsettings.json, appsettings.[EnvironmentName].json, variabili di ambiente, argomenti della riga di comando e altri origini di configurazione.Load configuration from appsettings.json, appsettings.{Environment Name}.json, environment variables, command line arguments, and other configuration sources.
  • Inviare l'output di registrazione alla console e ai provider di debug.Send logging output to the console and debug providers.

Per ulteriori informazioni, vedere Host generico .NET.For more information, see Host generico .NET.

Sono disponibili due host: l'host Web e l'host generico.Two hosts are available: the Web Host and the Generic Host. In ASP.NET Core 2.x, l'host generico è destinato solo agli scenari non Web.In ASP.NET Core 2.x, the Generic Host is only for non-web scenarios.

Il codice per creare un host si trova in Program.Main:The code to create a host is in Program.Main:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

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

Il metodo CreateDefaultBuilder configura un host con le opzioni usate comunemente, ad esempio:The CreateDefaultBuilder method configures a host with commonly used options, such as the following:

  • Usare Kestrel come server Web e abilitare l'integrazione IIS.Use Kestrel as the web server and enable IIS integration.
  • Caricare la configurazione da appsettings.json, appsettings.[EnvironmentName].json, variabili di ambiente, argomenti della riga di comando e altri origini di configurazione.Load configuration from appsettings.json, appsettings.{Environment Name}.json, environment variables, command line arguments, and other configuration sources.
  • Inviare l'output di registrazione alla console e ai provider di debug.Send logging output to the console and debug providers.

Per ulteriori informazioni, vedere Host Web ASP.NET Core.For more information, see Host Web ASP.NET Core.

Scenari non WebNon-web scenarios

L'host generico consente ad altri tipi di app di usare estensioni del framework trasversali quali la registrazione, l'inserimento delle dipendenze, la configurazione e la gestione del ciclo di vita delle app.The Generic Host allows other types of apps to use cross-cutting framework extensions, such as logging, dependency injection (DI), configuration, and app lifetime management. Per altre informazioni, vedere Host generico .NET e Attività in background con servizi ospitati in ASP.NET Core.For more information, see Host generico .NET and Attività in background con servizi ospitati in ASP.NET Core.

ServerServers

Un'app ASP.NET Core usa un'implementazione del server HTTP per l'ascolto delle richieste HTTP.An ASP.NET Core app uses an HTTP server implementation to listen for HTTP requests. Il server espone le richieste all'app sotto forma di insieme di funzionalità di richiesta strutturate in un HttpContext.The server surfaces requests to the app as a set of request features composed into an HttpContext.

ASP.NET Core include le implementazioni server seguenti:ASP.NET Core provides the following server implementations:

  • Kestrel è un server Web multipiattaforma.Kestrel is a cross-platform web server. Kestrel viene spesso eseguito in una configurazione con proxy inverso tramite IIS.Kestrel is often run in a reverse proxy configuration using IIS. In ASP.NET Core 2.0 o versione successiva Kestrel può essere eseguito come server perimetrale pubblico esposto direttamente a Internet.In ASP.NET Core 2.0 or later, Kestrel can be run as a public-facing edge server exposed directly to the Internet.
  • Server HTTP IIS è un server per Windows che usa IIS.IIS HTTP Server is a server for windows that uses IIS. Con questo server l'app ASP.NET Core e IIS sono eseguiti nello stesso processo.With this server, the ASP.NET Core app and IIS run in the same process.
  • HTTP.sys è un server per Windows che non viene usato con IIS.HTTP.sys is a server for Windows that isn't used with IIS.

ASP.NET Core include le implementazioni server seguenti:ASP.NET Core provides the following server implementations:

  • Kestrel è un server Web multipiattaforma.Kestrel is a cross-platform web server. Kestrel viene spesso eseguito in una configurazione con proxy inverso tramite IIS.Kestrel is often run in a reverse proxy configuration using IIS. In ASP.NET Core 2.0 o versione successiva Kestrel può essere eseguito come server perimetrale pubblico esposto direttamente a Internet.In ASP.NET Core 2.0 or later, Kestrel can be run as a public-facing edge server exposed directly to the Internet.
  • HTTP.sys è un server per Windows che non viene usato con IIS.HTTP.sys is a server for Windows that isn't used with IIS.

Per ulteriori informazioni, vedere Implementazioni di server Web in ASP.NET Core.For more information, see Implementazioni di server Web in ASP.NET Core.

ConfigurazioneConfiguration

ASP.NET Core offre un framework di configurazione che ottiene le impostazioni, ad esempio coppie nome-valore, da un set ordinato di provider di configurazione.ASP.NET Core provides a configuration framework that gets settings as name-value pairs from an ordered set of configuration providers. Esistono provider di configurazione predefiniti per un'ampia gamma di origini, ad esempio file con estensione JSON, file con estensione XML, variabili di ambiente e argomenti della riga di comando.There are built-in configuration providers for a variety of sources, such as .json files, .xml files, environment variables, and command-line arguments. È anche possibile scrivere provider di configurazione personalizzati.You can also write custom configuration providers.

Si potrebbe specificare, ad esempio, che la configurazione proviene da appsettings.json e da variabili di ambiente.For example, you could specify that configuration comes from appsettings.json and environment variables. Quindi, quando viene richiesto il valore di ConnectionString, il framework esaminerebbe per primo il file appsettings.json.Then when the value of ConnectionString is requested, the framework looks first in the appsettings.json file. Se il valore venisse trovato qui ma anche in una variabile di ambiente, il valore della variabile di ambiente avrebbe la precedenza.If the value is found there but also in an environment variable, the value from the environment variable would take precedence.

Per la gestione dei dati di configurazione riservati, ad esempio le password, ASP.NET Core offre uno strumento Secret Manager.For managing confidential configuration data such as passwords, ASP.NET Core provides a Secret Manager tool. Per i segreti di produzione, si consiglia di usare Azure Key Vault.For production secrets, we recommend Azure Key Vault.

Per ulteriori informazioni, vedere Configurazione in ASP.NET Core.For more information, see Configurazione in ASP.NET Core.

OpzioniOptions

Ove possibile, ASP.NET Core segue il modello di opzioni per archiviare e recuperare i valori di configurazione.Where possible, ASP.NET Core follows the options pattern for storing and retrieving configuration values. Il modello di opzioni usa le classi per rappresentare i gruppi di impostazioni correlate.The options pattern uses classes to represent groups of related settings.

Il codice seguente, ad esempio, imposta le opzioni WebSockets:For example, the following code sets WebSockets options:

var options = new WebSocketOptions  
{  
   KeepAliveInterval = TimeSpan.FromSeconds(120),  
   ReceiveBufferSize = 4096
};  
app.UseWebSockets(options);

Per ulteriori informazioni, vedere Modello di opzioni in ASP.NET Core.For more information, see Modello di opzioni in ASP.NET Core.

AmbientiEnvironments

Gli ambienti di esecuzione, ad esempio Sviluppo, Staging e Produzione, sono un concetto fondamentale in ASP.NET Core.Execution environments, such as Development, Staging, and Production, are a first-class notion in ASP.NET Core. È possibile specificare l'ambiente in cui viene eseguita un'app impostando la variabile di ambiente ASPNETCORE_ENVIRONMENT.You can specify the environment an app is running in by setting the ASPNETCORE_ENVIRONMENT environment variable. ASP.NET Core legge tale variabile di ambiente all'avvio dell'app e ne archivia il valore in un'implementazione IHostingEnvironment.ASP.NET Core reads that environment variable at app startup and stores the value in an IHostingEnvironment implementation. L'oggetto ambiente è disponibile in un punto qualsiasi dell'app tramite l'inserimento delle dipendenze.The environment object is available anywhere in the app via DI.

Il seguente codice di esempio della classe Startup configura l'app in modo che fornisca informazioni dettagliate sull'errore solo quando viene eseguita nell'ambiente di sviluppo:The following sample code from the Startup class configures the app to provide detailed error information only when it runs in development:

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

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

Per ulteriori informazioni, vedere Usare più ambienti in ASP.NET Core.For more information, see Usare più ambienti in ASP.NET Core.

RegistrazioneLogging

ASP.NET Core supporta un'API di registrazione che funziona con un'ampia gamma di provider di registrazione predefiniti e di terze parti.ASP.NET Core supports a logging API that works with a variety of built-in and third-party logging providers. Tra i provider disponibili sono inclusi i seguenti:Available providers include the following:

  • ConsoleConsole
  • DebugDebug
  • Event Tracing for WindowsEvent Tracing on Windows
  • Registro eventi di WindowsWindows Event Log
  • TraceSourceTraceSource
  • Servizio app di AzureAzure App Service
  • Azure Application InsightsAzure Application Insights

Scrivere i log da un punto qualsiasi del codice di un'app recuperando un oggetto ILogger dall'inserimento delle dipendenze e chiamando i metodi di registrazione.Write logs from anywhere in an app's code by getting an ILogger object from DI and calling log methods.

Ecco un esempio di codice che usa un oggetto ILogger con inserimento costruttore e chiamate al metodo di registrazione evidenziati.Here's sample code that uses an ILogger object, with constructor injection and the logging method calls highlighted.

public class TodoController : ControllerBase
{
    private readonly ILogger _logger;

    public TodoController(ILogger<TodoController> logger)
    {
        _logger = logger;
    }

    [HttpGet("{id}", Name = "GetTodo")]
    public ActionResult<TodoItem> GetById(string id)
    {
        _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
        // Item lookup code removed.
        if (item == null)
        {
            _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
            return NotFound();
        }
        return item;
    }
}

L'interfaccia ILogger consente di passare qualsiasi numero di campi al provider di registrazione.The ILogger interface lets you pass any number of fields to the logging provider. I campi vengono usati comunemente per costruire una stringa di messaggio, ma il provider può anche inviarli come campi separati a un archivio dati.The fields are commonly used to construct a message string, but the provider can also send them as separate fields to a data store. Questa funzionalità consente ai provider di registrazione di implementare la registrazione semantica, nota anche come registrazione strutturata.This feature makes it possible for logging providers to implement semantic logging, also known as structured logging.

Per ulteriori informazioni, vedere Registrazione in .NET Core e ASP.NET Core.For more information, see Registrazione in .NET Core e ASP.NET Core.

RoutingRouting

Una route è un modello URL di cui è stato eseguito il mapping su un gestore.A route is a URL pattern that is mapped to a handler. Il gestore è in genere una pagina Razor, un metodo di azione in un controller MVC o un tipo di middleware.The handler is typically a Razor page, an action method in an MVC controller, or a middleware. Il routing di ASP.NET Core consente di controllare gli URL usati dall'app.ASP.NET Core routing gives you control over the URLs used by your app.

Per ulteriori informazioni, vedere Routing in ASP.NET Core.For more information, see Routing in ASP.NET Core.

Gestione degli erroriError handling

ASP.NET Core dispone di funzionalità predefinite per la gestione degli errori, ad esempio:ASP.NET Core has built-in features for handling errors, such as:

  • Una pagina delle eccezioni per gli sviluppatoriA developer exception page
  • Pagine degli errori personalizzateCustom error pages
  • Pagine dei codici di stato staticheStatic status code pages
  • Gestione delle eccezioni durante l'avvioStartup exception handling

Per ulteriori informazioni, vedere Gestire gli errori in ASP.NET Core.For more information, see Gestire gli errori in ASP.NET Core.

Creare richieste HTTPMake HTTP requests

Un'implementazione di IHttpClientFactory è disponibile per la creazione di istanze HttpClient.An implementation of IHttpClientFactory is available for creating HttpClient instances. Il factory:The factory:

  • Offre una posizione centrale per la denominazione e la configurazione di istanze di HttpClient logiche.Provides a central location for naming and configuring logical HttpClient instances. Ad esempio, è possibile registrare e configurare un client github per accedere a GitHub.For example, a github client can be registered and configured to access GitHub. È possibile registrare un client predefinito per altri scopi.A default client can be registered for other purposes.
  • Supporta la registrazione e il concatenamento di più gestori di delega per creare una pipeline di middleware per le richieste in uscita.Supports registration and chaining of multiple delegating handlers to build an outgoing request middleware pipeline. Questo modello è simile alla pipeline di middleware in ingresso in ASP.NET Core.This pattern is similar to the inbound middleware pipeline in ASP.NET Core. Il modello offre un meccanismo per gestire le problematiche trasversali relative alle richieste HTTP, tra cui memorizzazione nella cache, gestione degli errori, serializzazione e registrazione.The pattern provides a mechanism to manage cross-cutting concerns around HTTP requests, including caching, error handling, serialization, and logging.
  • Si integra con Polly, una famosa libreria di terze parti per la gestione degli errori temporanei.Integrates with Polly, a popular third-party library for transient fault handling.
  • Gestisce il pooling e la durata delle istanze di HttpClientMessageHandler sottostanti per evitare problemi DNS comuni che si verificano quando le durate di HttpClient vengono gestite manualmente.Manages the pooling and lifetime of underlying HttpClientMessageHandler instances to avoid common DNS problems that occur when manually managing HttpClient lifetimes.
  • Aggiunge un'esperienza di registrazione configurabile, tramite ILogger, per tutte le richieste inviate attraverso i client creati dalla factory.Adds a configurable logging experience (via ILogger) for all requests sent through clients created by the factory.

Per ulteriori informazioni, vedere Effettuare richieste HTTP usando IHttpClientFactory in ASP.NET Core.For more information, see Effettuare richieste HTTP usando IHttpClientFactory in ASP.NET Core.

Radice del contenutoContent root

La radice del contenuto è il percorso di base di:The content root is the base path to the:

  • Eseguibile che ospita l'app (exe).Executable hosting the app (.exe).
  • Assembly compilati che costituiscono l'app ( . dll).Compiled assemblies that make up the app (.dll).
  • File di contenuto non di codice usati dall'app, ad esempio:Non-code content files used by the app, such as:
    • File Razor ( . cshtml, . Razor)Razor files (.cshtml, .razor)
    • File di configurazione (conestensione JSON, XML)Configuration files (.json, .xml)
    • File di dati ( . DB)Data files (.db)
  • Radice Web, in genere la cartella wwwroot pubblicata.Web root, typically the published wwwroot folder.

Durante lo sviluppo:During development:

  • Per impostazione predefinita, la radice del contenuto è la directory radice del progetto.The content root defaults to the project's root directory.
  • La directory radice del progetto viene utilizzata per creare:The project's root directory is used to create the:
    • Percorso dei file di contenuto non di codice dell'app nella directory radice del progetto.Path to the app's non-code content files in the project's root directory.
    • Radice Web, in genere la cartella wwwroot nella directory radice del progetto.Web root, typically the wwwroot folder in the project's root directory.

Quando si Compila l'host, è possibile specificare un percorso radice del contenuto alternativo.An alternative content root path can be specified when building the host. Per ulteriori informazioni, vedere Host generico .NET.For more information, see Host generico .NET.

Quando si Compila l'host, è possibile specificare un percorso radice del contenuto alternativo.An alternative content root path can be specified when building the host. Per ulteriori informazioni, vedere Host Web ASP.NET Core.For more information, see Host Web ASP.NET Core.

Radice WebWeb root

La radice Web è il percorso di base per i file di risorse pubblici, non di codice, statici, ad esempio:The web root is the base path to public, non-code, static resource files, such as:

  • Fogli di stile ( . CSS)Stylesheets (.css)
  • JavaScript ( . js)JavaScript (.js)
  • Immagini ( . png, . jpg)Images (.png, .jpg)

I file statici vengono serviti per impostazione predefinita solo dalla directory radice Web (e dalle sottodirectory).Static files are only served by default from the web root directory (and sub-directories).

Per impostazione predefinita, il percorso radice Web è {Content root}/wwwroot, ma è possibile specificare una radice Web diversa durante la compilazione dell'host.The web root path defaults to {content root}/wwwroot, but a different web root can be specified when building the host. Per ulteriori informazioni, vedere Host generico .NET.For more information, see Host generico .NET.

Per impostazione predefinita, il percorso radice Web è {Content root}/wwwroot, ma è possibile specificare una radice Web diversa durante la compilazione dell'host.The web root path defaults to {content root}/wwwroot, but a different web root can be specified when building the host. Per altre informazioni, vedere Web root (Radice Web).For more information, see Web root.

Impedire la pubblicazione di file in wwwroot con il contenuto<> elemento del progetto nel file di progetto.Prevent publishing files in wwwroot with the <Content> project item in the project file. Nell'esempio seguente viene impedita la pubblicazione di contenuto nella directory wwwroot/locale e nelle sottodirectory:The following example prevents publishing content in the wwwroot/local directory and sub-directories:

<ItemGroup>
  <Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" />
</ItemGroup>

Nei file Razor (conestensione cshtml) la barra tilde (~/) punta alla radice Web.In Razor (.cshtml) files, the tilde-slash (~/) points to the web root. Un percorso che inizia con ~/ viene definito percorso virtuale.A path beginning with ~/ is referred to as a virtual path.

Per ulteriori informazioni, vedere File statici in ASP.NET Core.For more information, see File statici in ASP.NET Core.