Condividi tramite


Usare ASP.NET API Core in una libreria di classi

Di Scott Addie

Questo documento fornisce indicazioni per l'uso delle API di base di ASP.NET in una libreria di classi. Per tutte le altre indicazioni sulle librerie, vedere indicazioni per librerie open source.

Determinare quali versioni di ASP.NET Core supportare

ASP.NET Core è conforme ai criteri di supporto di .NET Core. Consultare i criteri di supporto per determinare quali versioni di ASP.NET Core supportare in una libreria. Una libreria deve:

  • Eseguire uno sforzo per supportare tutte le versioni ASP.NET Core classificate come Long-Term Support (LTS).
  • Non sentirsi obbligati a supportare ASP.NET versioni Core classificate come End of Life (EOL).

Man mano che vengono rese disponibili le versioni di anteprima di ASP.NET Core, le modifiche di rilievo vengono pubblicate nel repository aspnet/Announcements GitHub. I test di compatibilità delle librerie possono essere eseguiti durante lo sviluppo di funzionalità del framework.

Usare il framework condiviso ASP.NET Core

Con il rilascio di .NET Core 3.0, molti assembly ASP.NET Core non vengono più pubblicati in NuGet come pacchetti. Gli assembly vengono invece inclusi nel framework condiviso Microsoft.AspNetCore.App, installato con .NET Core SDK e i programmi di installazione di runtime. Per un elenco dei pacchetti non più pubblicati, vedere Rimuovere i riferimenti ai pacchetti obsoleti.

A partire da .NET Core 3.0, i progetti che usano Microsoft.NET.Sdk.Web MSBuild SDK fanno riferimento in modo implicito al framework condiviso. I progetti che usano Microsoft.NET.Sdk o Microsoft.NET.Sdk.Razor SDK devono fare riferimento a ASP.NET Core per usare ASP.NET API Core nel framework condiviso.

Per fare riferimento a ASP.NET Core, aggiungere l'elemento <FrameworkReference> seguente al file di progetto:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

Includere Blazor estendibilità

Blazor supporta la creazione di componenti Razor in librerie di classi per le app lato server e lato client. Per supportare i componenti Razor in una libreria di classi, la libreria di classi deve usare il Microsoft.NET.Sdk.Razor SDK.

Supportare le app lato server e lato client

Per supportare il consumo del componente Razor sia da app lato server che lato client da una singola libreria, usare le istruzioni seguenti per l'editor.

Usare il modello di progetto libreria di classi Razor.

Nota

Non selezionare la casella di controllo Pagine di supporto e visualizzazioni. Se si seleziona la casella di controllo, viene restituita una libreria di classi che supporta solo le app lato server.

Libreria generata dal modello di progetto:

  • È destinato al framework .NET corrente basato sull'SDK installato.
  • Abilita i controlli di compatibilità del browser per verificare la presenza di dipendenze della piattaforma includendo browser come piattaforma supportata con l'elemento SupportedPlatform MSBuild.
  • Aggiunge un riferimento al pacchetto NuGet per Microsoft.AspNetCore.Components.Web.

RazorClassLibrary-CSharp.csproj (origine di riferimento)

Nota

I collegamenti alla documentazione della sorgente di riferimento .NET di solito caricano il ramo predefinito del repository, che rappresenta lo sviluppo attuale per la prossima versione di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Cambia branch o tag. Per ulteriori informazioni, vedere Come selezionare un tag di versione del codice sorgente di ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Supportare più versioni del framework

Se la libreria deve supportare le funzionalità aggiunte a Blazor nella versione corrente e allo stesso tempo supportare una o più versioni precedenti, configurarla per destinazioni multiple. Specificare un elenco delimitato da punto e virgola di moniker framework di destinazione (TFMs) nella proprietà TargetFrameworks MSBuild:

<TargetFrameworks>{TARGET FRAMEWORKS}</TargetFrameworks>

Nell'esempio precedente, il segnaposto {TARGET FRAMEWORKS} rappresenta l'elenco di TFMs delimitato da punto e virgola. Ad esempio, netcoreapp3.1;net5.0.

Supporta solo l'utilizzo lato server

Le librerie di classi vengono raramente costruite per supportare solo le applicazioni lato server. Se la libreria di classi richiede solo funzionalità specifiche del lato server, ad esempio l'accesso a CircuitHandler o Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorageo usa funzionalità specifiche di ASP.NET core, ad esempio middleware, controller MVC o pagine Razor, usare un degli approcci seguenti:

  • Specificare che la raccolta supporta pagine e visualizzazioni utilizzando la casella di controllo Supporto per pagine e visualizzazioni (Visual Studio) o l'opzione -s|--support-pages-and-views con il comando dotnet new:

    dotnet new razorclasslib -s
    
  • Fornire solo un riferimento al framework per ASP.NET Core nel file di progetto della libreria, oltre a qualsiasi altra proprietà MSBuild necessaria:

    <ItemGroup>
      <FrameworkReference Include="Microsoft.AspNetCore.App" />
    </ItemGroup>
    

Per altre informazioni sulle librerie contenenti componenti di Razor, vedere utilizzare componenti Razor di ASP.NET Core da una libreria di classi Razor.

Includi estendibilità MVC

Questa sezione illustra le raccomandazioni per le librerie che includono:

Questa sezione non illustra il multitargeting per supportare più versioni di MVC. Per indicazioni sul supporto di più versioni di ASP.NET Core, vedere Supportare più versioni ASP.NET Core.

Razor visualizzazioni o Razor pagine

Un progetto che include viste Razor o Razor Pages deve usare Microsoft.NET.Sdk.Razor SDK.

Se il progetto è destinato a .NET Core 3.x, è necessario:

  • Proprietà MSBuild AddRazorSupportForMvc impostata su true.
  • Elemento <FrameworkReference> per il framework condiviso.

Il Razor modello di progetto libreria di classi soddisfa i requisiti precedenti per i progetti destinati a .NET Core. Usare le istruzioni seguenti per l'editor.

Usare il modello di progetto libreria di classi Razor. È necessario selezionare la casella di controllo pagine di supporto e visualizzazioni del modello.

Per esempio:

<Project Sdk="Microsoft.NET.Sdk.Razor">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

Se invece il progetto è destinato a .NET Standard, è necessario un Riferimento al pacchetto Microsoft.AspNetCore.Mvc. Il pacchetto Microsoft.AspNetCore.Mvc è stato spostato nel framework condiviso di ASP.NET Core 3.0 e quindi non viene più pubblicato. Per esempio:

<Project Sdk="Microsoft.NET.Sdk.Razor">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
  </ItemGroup>

</Project>

Helper di tag

Un progetto che include helper tag deve usare Microsoft.NET.Sdk SDK. Se la destinazione è .NET Core 3.x, aggiungere un elemento <FrameworkReference> per il framework condiviso. Per esempio:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

Se la destinazione è .NET Standard (per supportare versioni precedenti a ASP.NET Core 3.x), aggiungere un riferimento al pacchetto a Microsoft.AspNetCore.Mvc.Razor. Il pacchetto Microsoft.AspNetCore.Mvc.Razor è stato spostato nel framework condiviso e pertanto non viene più pubblicato. Per esempio:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
  </ItemGroup>

</Project>

Visualizzare i componenti

Un progetto che include Visualizzare i componenti deve usare Microsoft.NET.Sdk SDK. Se la destinazione è .NET Core 3.x, aggiungere un elemento <FrameworkReference> per il framework condiviso. Per esempio:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

Se la destinazione è .NET Standard (per supportare versioni precedenti a ASP.NET Core 3.x), aggiungere un riferimento al pacchetto a Microsoft.AspNetCore.Mvc.ViewFeatures. Il pacchetto Microsoft.AspNetCore.Mvc.ViewFeatures è stato spostato nel framework condiviso e pertanto non viene più pubblicato. Per esempio:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
  </ItemGroup>

</Project>

Supportare più versioni di ASP.NET Core

Per creare una libreria che supporta più varianti di ASP.NET Core, è necessario il multitargeting. Si consideri uno scenario in cui una libreria helper tag deve supportare le varianti principali di ASP.NET seguenti:

  • ASP.NET Core 2.1 destinato a .NET Framework 4.6.1
  • ASP.NET Core 2.x destinato a .NET Core 2.x
  • ASP.NET Core 3.x destinato a .NET Core 3.x

Il file di progetto seguente supporta queste varianti tramite la proprietà TargetFrameworks:

<Project Sdk="Microsoft.NET.Sdk">
  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net461</TargetFrameworks>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Markdig" Version="0.16.0" />
  </ItemGroup>
  
  <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>

Con il file di progetto precedente:

  • Il pacchetto Markdig è stato aggiunto per tutti i consumatori.
  • Riferimento a Microsoft.AspNetCore.Mvc.Razor viene aggiunto per i consumer che puntano a .NET Framework 4.6.1 o versioni successive o .NET Core 2.x. La versione 2.1.0 del pacchetto funziona con ASP.NET Core 2.2 grazie alla compatibilità con le versioni precedenti.
  • Viene fatto riferimento al framework condiviso per i consumatori che puntano a .NET Core 3.x. Il pacchetto Microsoft.AspNetCore.Mvc.Razor è incluso nel framework condiviso.

In alternativa, si potrebbe mirare a .NET Standard 2.0 invece di destinare sia .NET Core 2.1 che .NET Framework 4.6.1.

<Project Sdk="Microsoft.NET.Sdk">
  
  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;netcoreapp3.1</TargetFrameworks>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Markdig" Version="0.16.0" />
  </ItemGroup>
  
  <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>

Con il file di progetto precedente, esistono le avvertenze seguenti:

  • Poiché la libreria contiene solo helper tag, è più semplice definire come destinazione le piattaforme specifiche in cui ASP.NET Core viene eseguito: .NET Core e .NET Framework. Gli helper tag non possono essere usati da altri framework di destinazione conformi a .NET Standard 2.0, ad esempio Unity e UWP.
  • L'uso di .NET Standard 2.0 da .NET Framework presenta alcuni problemi risolti in .NET Framework 4.7.2. È possibile migliorare l'esperienza per gli utenti che usano la gamma di versioni .NET Framework dalla 4.6.1 alla 4.7.1 puntando alla versione 4.6.1.

Se la libreria deve chiamare API specifiche della piattaforma, specificare come destinazione implementazioni .NET invece di .NET Standard. Per altre informazioni, vedere multitargeting.

Usare un'API che non è stata modificata

Si immagini uno scenario in cui si sta aggiornando una libreria middleware da .NET Core 2.2 a 3.1. Le API middleware di ASP.NET Core usate nella libreria non sono cambiate tra ASP.NET Core 2.2 e 3.1. Per continuare a supportare la libreria middleware in .NET Core 3.1, seguire questa procedura:

  • Seguire le indicazioni della libreria standard .
  • Aggiungere un riferimento al pacchetto per ogni pacchetto API di NuGet se l'assembly corrispondente non esiste nel framework condiviso.

Usare un'API modificata

Si immagini uno scenario in cui si sta aggiornando una libreria da .NET Core 2.2 a .NET Core 3.1. Un'API core ASP.NET usata nella libreria ha una modifica di rilievo in ASP.NET Core 3.1. Valutare se la libreria può essere riscritta per non usare l'API interrotta in tutte le versioni.

Se è possibile riscrivere la libreria, eseguire questa operazione e continuare a usare un framework di destinazione precedente ,ad esempio .NET Standard 2.0 o .NET Framework 4.6.1 con riferimenti al pacchetto.

Se non è possibile riscrivere la libreria, seguire questa procedura:

  • Aggiungere un obiettivo per .NET Core 3.1.
  • Aggiungere un elemento <FrameworkReference> per il framework condiviso.
  • Usare la direttiva del preprocessore #if con il simbolo appropriato del framework di destinazione per la compilazione condizionale del codice.

Ad esempio, le letture e le scritture sincrone nei flussi di richiesta e risposta HTTP sono disabilitate per impostazione predefinita a partire da ASP.NET Core 3.1. ASP.NET Core 2.2 supporta il comportamento sincrono per impostazione predefinita. Si consideri una libreria middleware in cui le letture e le scritture sincrone devono essere abilitate in caso di I/O. La libreria deve racchiudere il codice per abilitare le funzionalità sincrone nella direttiva del preprocessore appropriata. Per esempio:

public async Task Invoke(HttpContext httpContext)
{
    if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
    {
        httpContext.Response.StatusCode = (int) HttpStatusCode.OK;
        httpContext.Response.ContentType = "application/json";
        httpContext.Response.ContentLength = _bufferSize;

#if !NETCOREAPP3_1 && !NETCOREAPP5_0
        var syncIOFeature = httpContext.Features.Get<IHttpBodyControlFeature>();
        if (syncIOFeature != null)
        {
            syncIOFeature.AllowSynchronousIO = true;
        }

        using (var sw = new StreamWriter(
            httpContext.Response.Body, _encoding, bufferSize: _bufferSize))
        {
            _json.Serialize(sw, new JsonMessage { message = "Hello, World!" });
        }
#else
        await JsonSerializer.SerializeAsync<JsonMessage>(
            httpContext.Response.Body, new JsonMessage { message = "Hello, World!" });
#endif
        return;
    }

    await _next(httpContext);
}

Usare un'API introdotta nella versione 3.1

Si supponga di voler usare un'API ASP.NET Core introdotta in ASP.NET Core 3.1. Considerare le domande seguenti:

  1. La libreria richiede funzionalmente la nuova API?
  2. La libreria può implementare questa funzionalità in modo diverso?

Se la libreria richiede funzionalmente l'API e non è possibile implementarla di livello inferiore:

  • Destina solo a .NET Core 3.x.
  • Aggiungere un elemento <FrameworkReference> per il framework condiviso.

Se la libreria può implementare la funzionalità in modo diverso:

  • Aggiungere .NET Core 3.x come framework di destinazione.
  • Aggiungere un elemento <FrameworkReference> per il framework condiviso.
  • Usare la direttiva del preprocessore #if con il simbolo del framework di destinazione appropriato per compilare il codice in modo condizionale.

Ad esempio, l'helper tag seguente usa l'interfaccia IWebHostEnvironment introdotta in ASP.NET Core 3.1. I consumatori che mirano a .NET Core 3.1 eseguono il percorso di codice definito dal simbolo del target del framework NETCOREAPP3_1. Il parametro di tipo del costruttore del Tag Helper cambia in IHostingEnvironment per i consumer di .NET Core 2.1 e .NET Framework 4.6.1. Questa modifica è stata necessaria perché ASP.NET Core 3.1 ha contrassegnato IHostingEnvironment come obsoleto e consigliato IWebHostEnvironment come sostituzione.

[HtmlTargetElement("script", Attributes = "asp-inline")]
public class ScriptInliningTagHelper : TagHelper
{
    private readonly IFileProvider _wwwroot;

#if NETCOREAPP3_1
    public ScriptInliningTagHelper(IWebHostEnvironment env)
#else
    public ScriptInliningTagHelper(IHostingEnvironment env)
#endif
    {
        _wwwroot = env.WebRootFileProvider;
    }

    // code omitted for brevity
}

Il seguente file di progetto multi-destinazione supporta questo scenario Tag Helper.

<Project Sdk="Microsoft.NET.Sdk">
  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net461</TargetFrameworks>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Markdig" Version="0.16.0" />
  </ItemGroup>
  
  <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>

Usare un'API rimossa dal framework condiviso

Per usare un assembly ASP.NET Core rimosso dal framework condiviso, aggiungere il riferimento al pacchetto appropriato. Per un elenco dei pacchetti rimossi dal framework condiviso in ASP.NET Core 3.1, vedere Rimuovere i riferimenti ai pacchetti obsoleti.

Ad esempio, per aggiungere il client API Web:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
  </ItemGroup>

</Project>

Risorse aggiuntive