Migrace z ASP.NET na ASP.NET Core

Petr Levin

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

Požadavky

.NET Core SDK 2.2 nebo novější

Cílové architektury

ASP.NET Core projekty nabízejí vývojářům flexibilitu při cílení na .NET Core, .NET Framework nebo obojí. V tématu Volba mezi .NET Core a .NET Framework pro serverové aplikace zjistěte, která cílová rozhraní je nejvhodnější.

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

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

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

Při použití metabalíku se s aplikací nasadí žádné balíčky odkazované v metabalíku. Úložiště modulu runtime .NET Core zahrnuje tyto prostředky a jsou předkompilované, aby se zlepšil výkon. Další Microsoft.AspNetCore.App v tématu ASP.NET Core metapackage.

Project struktury

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

  • Explicitní zahrnutí souborů není nutné, aby se považovaly za součást projektu. Tím se snižuje riziko konfliktů sloučení XML při práci na velkých týmech.

  • Neexistují žádné odkazy na jiné projekty založené na identifikátorech GUID, což zlepšuje čitelnost souborů.

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

    Úprava možnosti místní nabídky CSPROJ v Visual Studio 2017

Nahrazení souboru Global.asax

ASP.NET Core jsme nový mechanismus pro spuštění aplikace. Vstupním bodem pro ASP.NET je soubor Global.asax. Úlohy, jako je konfigurace tras, registrace filtrů a 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 zomení aplikaci a server, na který je nasazena, způsobem, který narušuje implementaci. Ve snaze o oddělení bylo zavedeno rozhraní OWIN, které poskytuje čistší způsob, jak používat více architektur najednou. OWIN poskytuje kanál pro přidání pouze potřebných modulů. Hostitelské prostředí využívá funkci Startup ke konfiguraci služeb a kanálu požadavků aplikace. Startup zaregistruje v aplikaci sadu middlewaru. Pro každý požadavek aplikace volá každou komponentu middlewaru s ukazatelem head 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 jednu nebo více obslužných rutin. Toho se dosáhne vrácením odkazu na obslužnou rutinu, která je novou hlavičkou seznamu. Každá obslužná rutina je zodpovědná za zapamatování a vyvolání další obslužné rutiny v seznamu. V ASP.NET Core je vstupním bodem aplikace a už nemáte závislost Startup na souboru 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í hodnota je XmlSerialization přes JSON. Podle potřeby přidejte do tohoto kanálu další middleware (načítání služeb, nastavení konfigurace, statické soubory atd.).

ASP.NET Core používá podobný přístup, ale nespoléhá se na OWIN, aby tuto položku zvládl. Místo toho se to provádí pomocí metody Program.cs Main (podobně jako konzolové aplikace) a Startup načítá 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 Configure metodu . V Configure souboru přidejte potřebný middleware do kanálu. V následujícím příkladu (z výchozí šablony webu) rozšiřující metody nakonfigurují kanál s podporou pro:

  • Chybové stránky
  • HTTP Strict Transport Security
  • 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ři přechodu na jinou platformu.

Poznámka

Podrobnější informace o spuštění a middlewaru ASP.NET Core najdete v tématu Startup in ASP.NET Core

Ukládání konfigurací

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

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

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

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

ASP.NET Core do libovolného souboru ukládat konfigurační data aplikace a načítat je jako součást spuš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 v aplikaci se provádí v souboru Startup.cs:

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

public IConfiguration Configuration { get; }

Aplikace čte z Configuration a načítá nastavení:

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

Existují 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 založený na dinachu poskytuje sadu objektů konfigurace silného typu.

// 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 konfigurace ASP.NET Core v tématu Konfigurace v ASP.NET Core.

Injektáž nativních závislostí

Důležitým cílem při vytváření rozsáhlých škálovatelných aplikací je volné párování komponent a služeb. Injektáž závislostí je oblíbená technika, jak toho dosáhnout, a je to nativní komponenta ASP.NET Core.

V ASP.NET aplikací spoléhají vývojáři při implementaci injektáže závislostí na knihovnu třetí strany. Jednou z takových knihoven je Unity, kterou poskytuje Microsoft Patterns & Practices.

Příkladem nastavení injektáže závislostí pomocí Unity je IDependencyResolver implementace, 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 , zaregistrujte službu a nastavte překladač závislostí na UnityContainer novou instanci pro váš HttpConfiguration UnityResolver kontejner:

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.
}

Vložení IProductRepository tam, kde je 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 ASP.NET Core, můžete přidat službu do metody ConfigureServices souboru Startup.cs:

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

Úložiště je možné vloženého kamkoli, jak to bylo u Unity pravda.

Poznámka

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

Zobrazování statických souborů

Důležitou součástí vývoje webu je schopnost obsluhovat statické prostředky na straně klienta. Nejběžnější 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 na CDN) a odkazovat na ně, aby je mohl načíst požadavek. Tento proces se v ASP.NET Core.

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

V ASP.NET Core jsou statické soubory uložené v kořenovém adresáři webu (kořen obsahu < > /wwwroot), pokud není nakonfigurované jinak. Soubory se načítá 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 .NET Framework, nainstalujte NuGet balíček Microsoft.AspNetCore.StaticFiles .

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

Poznámka

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

Více hodnot cookie s

Funkce s cookie více hodnotami se v ASP.NET Core. Vytvořte jednu cookie pro každou hodnotu.

Ověřování cookie nejsou komprimovaná v ASP.NET Core

Z bezpečnostních důvodů se cookie ověřování ve ASP.NET Core komprimuje. Při použití ověřování by vývojáři měli minimalizovat počet zahrnutých informací o deklaraci identity jenom tak, aby to cookie bylo nezbytné pro jejich potřeby.

Částečná migrace aplikace

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 pouze z ASP.NET 4.x do ASP.NET Core a zachování struktury adresy URL aplikace. Představte si například strukturu adresy URL aplikace zapplicationHost.config souboru:

<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 formátovací metody vstupu

Předchozí verze ASP.NET používaly atribut k ochraně před útoky typu [Bind] overposting. Formátovací metody vstupu fungují v různých ASP.NET Core. Atribut už není navržený tak, aby při použití se vstupními formátovacími metodami zabránilo přeúčtování k [Bind] parsování FORMÁTU JSON nebo XML. Tyto atributy ovlivňují vazbu modelu, pokud zdroj dat tvoří data, která jsou publikována s x-www-form-urlencoded typem obsahu.

U aplikací, které zapisují informace JSON do kontrolerů a k parsování dat používají formátovací metody vstupu JSON, doporučujeme nahradit atribut modelem zobrazení, který odpovídá vlastnostem definovaným [Bind] [Bind] atributem .

Další zdroje informací