Migrace z ASP.NET na ASP.NET Core

Autor: Isaac Levin

Tento článek slouží jako referenční příručka pro migraci aplikací ASP.NET do ASP.NET Core. Kompletní průvodce portováním existujících ASP.NET aplikací do .NET Core najdete v e-booku.

Požadavky

.NET Core SDK 2.2 nebo novější

Cílové architektury

ASP.NET Core projekty nabízejí vývojářům flexibilitu cílení na .NET Core, .NET Framework nebo obojí. Pokud chcete určit nejvhodnější cílovou architekturu, přečtěte si téma Volba mezi .NET Core a .NET Framework serverových aplikací.

Při cílení na .NET Framework musí projekty odkazovat na jednotlivé balíčky NuGet.

Cílení na .NET Core umožňuje eliminovat mnoho explicitních odkazů na balíčky díky ASP.NET Core metapackage. Microsoft.AspNetCore.App Nainstalujte metabalík do projektu:

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

Při použití metabalíku se s aplikací nenabízejí žádné balíčky, na které se v metabalíku odkazuje. Úložiště modulu runtime .NET Core zahrnuje tyto prostředky a jsou předem komkompilovány za účelem zvýšení výkonu. Další podrobnosti najdete v Microsoft.AspNetCore.App metabalíku pro ASP.NET Core.

rozdíly ve struktuře Project

Formát .csproj souboru byl v ASP.NET Core zjednodušený. Mezi některé z nájemných změn patří:

  • Explicitní zahrnutí souborů není nutné, aby byly považovány za součást projektu. To snižuje riziko konfliktů při slučování XML při práci na velkých týmech.

  • V jiných projektech nejsou žádné odkazy založené na identifikátoru GUID, což zlepšuje čitelnost souborů.

  • Soubor lze upravit bez jeho uvolnění v Visual Studio:

    Edit CSPROJ context menu option in Visual Studio 2017

Nahrazení souboru Global.asax

ASP.NET Core zavedl nový mechanismus spouštění aplikace. Vstupním bodem pro ASP.NET aplikace je soubor Global.asax. Úlohy, jako je konfigurace trasy a registrace oblastí, se zpracovávají v souboru Global.asax .

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

Tento přístup spojuje aplikaci a server, ke kterému je nasazena způsobem, který brání implementaci. V rámci úsilí o oddělení byl OWIN zaveden, aby poskytoval přehlednější způsob, jak společně používat více architektur. OWIN poskytuje kanál pro přidání pouze potřebných modulů. Hostitelské prostředí přebírá funkci Po spuštění ke konfiguraci služeb a kanálu žádostí aplikace. Startup zaregistruje sadu middlewaru v aplikaci. Pro každý požadavek aplikace volá jednotlivé komponenty middlewaru s ukazatelem hlavy propojeného seznamu na existující sadu obslužných rutin. Každá komponenta middlewaru může do kanálu zpracování požadavků přidat jeden nebo více obslužných rutin. Toho dosáhnete vrácením odkazu na obslužnou rutinu, která je novou hlavou seznamu. Každá obslužná rutina zodpovídá za zapamatování a vyvolání další obslužné rutiny v seznamu. Při ASP.NET Core je vstupní bod aplikace Startupa už nemáte závislost na global.asax. Při použití OWIN s .NET Framework použijte jako kanál něco podobného:

using Owin;
using System.Web.Http;

namespace WebApi
{
    // Note: By default all requests go through this OWIN pipeline. Alternatively you can turn this off by adding an appSetting owin:AutomaticAppStartup with value “false”. 
    // With this turned off you can still have OWIN apps listening on specific routes by adding routes in global.asax file using MapOwinPath or MapOwinRoute extensions on RouteTable.Routes
    public class Startup
    {
        // Invoked once at startup to configure your application.
        public void Configuration(IAppBuilder builder)
        {
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute("Default", "{controller}/{customerID}", new { controller = "Customer", customerID = RouteParameter.Optional });

            config.Formatters.XmlFormatter.UseXmlSerializer = true;
            config.Formatters.Remove(config.Formatters.JsonFormatter);
            // config.Formatters.JsonFormatter.UseDataContractJsonSerializer = true;

            builder.UseWebApi(config);
        }
    }
}

Tím se nakonfigurují výchozí trasy a výchozí hodnoty xmlSerialization přes Json. Podle potřeby přidejte do tohoto kanálu další middleware (načítání služeb, nastavení konfigurace, statických souborů atd.).

ASP.NET Core používá podobný přístup, ale nespoléhá na to, že OWIN zpracovává položku. Místo toho se to provádí metodou Program.csMain (podobně jako konzolové aplikace) a Startup načte se tam.

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

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

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

Startup musí obsahovat metodu Configure . Do Configurekanálu přidejte potřebný middleware. V následujícím příkladu (z výchozí šablony webu) nakonfigurují metody rozšíření kanál s podporou pro:

  • Chybové stránky
  • Zabezpečení striktního přenosu HTTP
  • Přesměrování HTTP na HTTPS
  • ASP.NET Core MVC
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

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

Hostitel a aplikace jsou oddělené, což v budoucnu poskytuje flexibilitu přechodu na jinou platformu.

Poznámka

Podrobnější informace o ASP.NET Core startupu a middlewaru najdete v tématu Spuštění v ASP.NET Core

Ukládání konfigurací

ASP.NET podporuje ukládání nastavení. Toto nastavení se používá například k podpoře prostředí, do kterého byly aplikace nasazené. Běžným postupem bylo uložit všechny vlastní páry klíč-hodnota v <appSettings> části souboru Web.config :

<appSettings>
  <add key="UserName" value="User" />
  <add key="Password" value="Password" />
</appSettings>

Aplikace čtou ConfigurationManager.AppSettings tato nastavení pomocí kolekce v System.Configuration oboru názvů:

string userName = System.Web.Configuration.ConfigurationManager.AppSettings["UserName"];
string password = System.Web.Configuration.ConfigurationManager.AppSettings["Password"];

ASP.NET Core může ukládat konfigurační data pro aplikaci v libovolném souboru a načíst je jako součást spouštění middlewaru. Výchozí soubor použitý v šablonách projektů je appsettings.json:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "AppConfiguration": {
    "UserName": "UserName",
    "Password": "Password"
  }
}

Načtení tohoto souboru do instance IConfiguration uvnitř vaší aplikace se provádí v Startup.cs:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

Aplikace načítá Configuration z nastavení:

string userName = Configuration.GetSection("AppConfiguration")["UserName"];
string password = Configuration.GetSection("AppConfiguration")["Password"];

Existuje rozšíření tohoto přístupu, aby byl proces robustnější, například použití injektáže závislostí (DI) k načtení služby s těmito hodnotami. Přístup DI poskytuje sadu objektů konfigurace se silným typem.

// Assume AppConfiguration is a class representing a strongly-typed version of AppConfiguration section
services.Configure<AppConfiguration>(Configuration.GetSection("AppConfiguration"));

Poznámka

Podrobnější informace o konfiguraci ASP.NET Core najdete v tématu Konfigurace v ASP.NET Core.

Injektáž nativních závislostí

Důležitým cílem při sestavování velkých škálovatelných aplikací je volné spojení komponent a služeb. Injektáž závislostí je oblíbená technika pro dosažení tohoto cíle a jedná se o nativní součást ASP.NET Core.

V ASP.NET aplikacích vývojáři spoléhají na knihovnu třetích stran k implementaci injektáže závislostí. Jednou z těchto knihoven je Unity poskytovaná postupy Microsoft Patterns & .

Příkladem nastavení injektáže závislostí pomocí Unity je implementace IDependencyResolver , která zabalí UnityContainer:

using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;

public class UnityResolver : IDependencyResolver
{
    protected IUnityContainer container;

    public UnityResolver(IUnityContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }
        this.container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return container.Resolve(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return container.ResolveAll(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return new List<object>();
        }
    }

    public IDependencyScope BeginScope()
    {
        var child = container.CreateChildContainer();
        return new UnityResolver(child);
    }

    public void Dispose()
    {
        Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        container.Dispose();
    }
}

Vytvořte instanci, UnityContainerzaregistrujte službu a nastavte překladač HttpConfiguration závislostí na novou instanci kontejneru UnityResolver :

public static void Register(HttpConfiguration config)
{
    var container = new UnityContainer();
    container.RegisterType<IProductRepository, ProductRepository>(new HierarchicalLifetimeManager());
    config.DependencyResolver = new UnityResolver(container);

    // Other Web API configuration not shown.
}

Vkládat IProductRepository tam, kde je to potřeba:

public class ProductsController : ApiController
{
    private IProductRepository _repository;

    public ProductsController(IProductRepository repository)  
    {
        _repository = repository;
    }

    // Other controller methods not shown.
}

Vzhledem k tomu, že injektáž závislostí je součástí ASP.NET Core, můžete službu přidat do ConfigureServices metody Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    // Add application services.
    services.AddTransient<IProductRepository, ProductRepository>();
}

Úložiště je možné vloženého kamkoli, stejně jako v Unity.

Poznámka

Další informace o injektáži závislostí najdete v tématu Injektáž závislostí.

Obsluha statických souborů

Důležitou součástí vývoje webu je schopnost obsluhovat statické prostředky na straně klienta. Nejběžnějšími příklady statických souborů jsou HTML, CSS, JavaScript a obrázky. Tyto soubory je potřeba uložit do publikovaného umístění aplikace (nebo CDN) a odkazovat na tyto soubory, aby je bylo možné načíst požadavkem. Tento proces se v ASP.NET Core změnil.

V ASP.NET jsou statické soubory uloženy v různých adresářích a odkazovány v zobrazeních.

V ASP.NET Core se statické soubory ukládají v kořenovém adresáři webu (<root> obsahu nebo wwwroot), pokud není nakonfigurované jinak. Soubory se načtou do kanálu požadavku vyvoláním UseStaticFiles metody rozšíření z Startup.Configure:

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

Poznámka

Pokud cílíte na .NET Framework, nainstalujte balíček Microsoft.AspNetCore.StaticFilesNuGet .

Například prostředek obrázku ve složce wwwroot/images je přístupný prohlížeči v umístění, například http://<app>/images/<imageFileName>.

Poznámka

Podrobnější informace o poskytování statických souborů v ASP.NET Core najdete v tématu Statické soubory.

Více hodnot cookie

Vícehodnotové hodnoty cookie nejsou v ASP.NET Core podporované. Vytvořte jednu cookie hodnotu.

V ASP.NET Core nejsou komprimované ověřování cookie

Z ASP.NET Core bezpečnostníchdůvodůch cookie Při použití ověřování cookieby vývojáři měli minimalizovat počet informací o deklarací identity, které jsou zahrnuté jenom na to, co je potřeba pro jejich potřeby.

Částečná migrace aplikací

Jedním z přístupů k částečné migraci aplikací je vytvoření dílčí aplikace SLUŽBY IIS a přesunutí určitých tras z ASP.NET 4.x na ASP.NET Core při zachování struktury adresy URL aplikace. Představte si například strukturu adres URL aplikace ze souboruapplicationHost.config :

<sites>
    <site name="Default Web Site" id="1" serverAutoStart="true">
        <application path="/">
            <virtualDirectory path="/" physicalPath="D:\sites\MainSite\" />
        </application>
        <application path="/api" applicationPool="DefaultAppPool">
            <virtualDirectory path="/" physicalPath="D:\sites\netcoreapi" />
        </application>
        <bindings>
            <binding protocol="http" bindingInformation="*:80:" />
            <binding protocol="https" bindingInformation="*:443:" sslFlags="0" />
        </bindings>
    </site>
	...
</sites>

Adresářová struktura:

.
├── MainSite
│   ├── ...
│   └── Web.config
└── NetCoreApi
    ├── ...
    └── web.config

[BIND] a vstupní formátovací moduly

Předchozí verze ASP.NET používaly [Bind] atribut k ochraně před útoky proti nadměrnému umístění. Vstupní formátovací moduly fungují v ASP.NET Core odlišně. Atribut [Bind] už není navržený tak, aby se zabránilo přeúčtování při použití se vstupními formátovacími moduly k analýze JSON nebo XML. Tyto atributy mají vliv na vazbu modelu, když zdroj dat je formulářová data publikovaná s typem x-www-form-urlencoded obsahu.

Pro aplikace, které publikují informace JSON na kontrolery a používají k parsování dat vstupní formát JSON, doporučujeme nahradit [Bind] atribut modelem zobrazení, který odpovídá vlastnostem definovaným atributem [Bind] .

Další materiály