Meningkatkan dari ASP.NET Framework ke ASP.NET Core

Mengapa meningkatkan ke .NET terbaru

ASP.NET Core adalah kerangka kerja web modern untuk .NET. Meskipun ASP.NET Core memiliki banyak kesamaan dengan ASP.NET dalam .NET Framework, ini adalah kerangka kerja baru yang sepenuhnya ditulis ulang. ASP.NET aplikasi yang diperbarui ke ASP.NET Core dapat memperoleh manfaat dari peningkatan performa dan akses ke fitur dan kemampuan pengembangan web terbaru.

pendekatan pembaruan ASP.NET Framework

Sebagian besar aplikasi ASP.NET Framework yang tidak sepele harus mempertimbangkan untuk menggunakan pendekatan peningkatan bertahas . Untuk informasi selengkapnya, lihat Peningkatan inkremental ASP.NET ke ASP.NET Core.

Untuk ASP.NET aplikasi MVC dan Web API, lihat Pelajari cara meningkatkan dari ASP.NET MVC dan Api Web ke ASP.NET Core MVC. Untuk aplikasi ASP.NET Framework Web Forms, lihat Pelajari cara meningkatkan dari ASP.NET Web Forms ke ASP.NET Core.

Pola aplikasi web yang andal

Lihat video dan artikel Reliable Web App Pattern for.NETYouTube untuk panduan tentang membuat aplikasi modern, andal, berkinerja, dapat diuji, hemat biaya, dan dapat diskalakan ASP.NET Core, baik dari awal atau refaktor aplikasi yang ada.

Perbedaan dekode URI antara ASP.NET ke ASP.NET Core

ASP.NET Core memiliki perbedaan dekode URI berikut dengan ASP.NET Framework:

ASCII Dikodekan Inti ASP.NET kerangka kerja ASP.NET
\ %5C \ /
/ %2F %2F /

Saat mendekode %2F pada ASP.NET Core:

  • Seluruh jalur tidak dilewati kecuali %2F karena mengonversinya akan / mengubah struktur jalur. Ini tidak dapat didekodekan sampai jalur dibagi menjadi segmen.

Untuk menghasilkan nilai untuk HttpRequest.Url, gunakan new Uri(this.AspNetCoreHttpRequest.GetEncodedUrl()); untuk menghindari Uri salah menafsirkan nilai.

Memigrasikan Rahasia Pengguna dari ASP.NET Framework ke ASP.NET Core

Lihat masalah GitHub ini.

Artikel ini berfungsi sebagai panduan referensi untuk memigrasikan aplikasi ASP.NET ke ASP.NET Core.

Visual Studio memiliki alat untuk membantu memigrasikan aplikasi ASP.NET ke ASP.NET Core. Untuk mengetahui informasi selengkapnya, lihat Memigrasikan dari ASP.NET ke ASP.NET Core di Visual Studio.

.NET Upgrade Assistant adalah alat baris perintah yang dapat membantu dalam proses migrasi dari ASP.NET ke ASP.NET Core. Untuk mendapatkan informasi selengkapnya, baca artikel Gambaran Umum .NET Upgrade Assistant dan Meningkatkan aplikasi ASP.NET MVC ke .NET 6 menggunakan .NET Upgrade Assistant.

Baca ebook berjudul Memindahkan aplikasi ASP.NET eksisting ke .NET Core untuk mendapatkan panduan lengkap mengenai pemindahan tersebut.

Prasyarat

.NET Core SDK 2.2 atau yang lebih baru

Kerangka kerja target

Proyek ASP.NET Core memberikan pilihan kepada pengembang untuk menarget .NET Core, .NET Framework, maupun keduanya. Baca Memilih antara .NET Core dan .NET Framework untuk aplikasi server guna menentukan kerangka kerja target yang paling tepat.

Saat menarget proyek.NET Framework, proyek harus mereferensikan paket NuGet individu.

Dengan menarget .NET Core, Anda dapat menyingkirkan sejumlah referensi paket eksplisit. Ini semua berkat metapackage ASP.NET Core. Instal metapackage Microsoft.AspNetCore.App di proyek Anda:

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

Bila Anda menggunakan metapackage tersebut, paket yang direferensikan di dalam metapackage akan disebarkan menggunakan aplikasi. Aset-aset yang terdapat dalam .NET Core Runtime Store ini dikompilasikan sebelumnya demi meningkatkan performa. Baca Metapackage Microsoft.AspNetCore.App untuk ASP.NET Core guna mendapatkan informasi selengkapnya.

Perbedaan struktur proyek

Format file .csproj di ASP.NET Core kini lebih sederhana. Sejumlah perubahan signifikannya, antara lain:

  • Tidak perlu penyertaan file secara eksplisit agar file tersebut dianggap sebagai bagian dari proyek. Alhasil, risiko konflik karena penggabungan XML saat mengelola tim yang besar dapat ditekan.

  • Tanpa referensi berbasis GUID ke proyek lain sehingga meningkatkan keterbacaan file.

  • File dapat diedit tanpa perlu memuatnya di Visual Studio:

    Edit CSPROJ context menu option in Visual Studio 2017]

Penggantian file Global.asax

ASP.NET meluncurkan mekanisme anyar untuk mem-bootstrap suatu aplikasi. Titik masuk untuk aplikasi ASP.Net adalah file Global.asax. Tugas-tugas, misalnya konfigurasi dan filter rute serta pendaftaran area, ditangani di dalam file 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);
    }
}

Metode ini menggabungkan aplikasi dan server tempat penyebarannya dengan cara yang mengganggu implementasinya. Guna melakukan pemisahan, kami memperkenalkan OWIN agar tersedia cara yang lebih sederhana untuk menggunakan sejumlah kerangka kerja sekaligus. OWIN menyediakan suatu alur sehingga Anda hanya perlu menambahkan modul yang dibutuhkan. Lingkungan hosting menggunakan fungsi Startup untuk mengonfigurasi layanan dan alur permintaan aplikasi. Startup menyimpan serangkaian middleware dengan aplikasi. Untuk setiap permintaan, aplikasi akan memanggil setiap komponen middleware dengan pointer kepala untuk daftar tertaut ke serangkaian handler yang ada. Tiap komponen middleware dapat menambahkan satu handler atau lebih ke alur yang menangani permintaan. Caranya adalah dengan mengembalikan suatu referensi ke handler yang merupakan kepala baru untuk daftar tersebut. Tiap handler berfungsi untuk mengingat dan memanggil handler berikutnya yang ada dalam daftar. Dengan ASP.NET Core, titik masuk ke aplikasi adalah Startup, dan Anda tidak lagi memiliki dependensi di Global.asax. Saat Anda menggunakan OWIN dengan .NET Framework, gunakan alur seperti yang berikut:

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

Alur ini akan mengonfigurasi rute default dan mendefault ke XmlSerialization melalui Json. Tambahkan Middleware lain ke alur ini seperlunya (memuat layanan, konfigurasi, pengaturan, file statik, dll.).

ASP.NET Core menggunakan metode serupa, tetapi tidak mengandalkan OWIN untuk menangani entrinya. Sebaliknya, proses tersebut dilakukan menggunakan metode Program.csMain (serupa aplikasi konsol) dan Startup dimuat dari sana.

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 harus menyertakan metode Configure. Di Configure, tambahkan middleware yang dibutuhkan ke alurnya. Dalam contoh berikut (dari templat situs default), metode ekstensi mengonfigurasi alur dengan dukungan untuk:

  • Halaman kesalahan
  • Keamanan Transportasi Ketat HTTP
  • Pengalihan HTTP ke HTTPS
  • ASP.NET Core MVC
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

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

Hosting dan aplikasi telah dipisahkan. Dengan begitu, pemindahan ke platform lain jadi kian mudah jika Anda ingin melakukannya kelak.

Catatan

Untuk mengetahui seluk-beluk Startup ASP.NET dan Middleware, baca Startup di ASP.NET Core

Konfigurasi penyimpanan

ASP.NET mendukung pengaturan penyimpanan. Pengaturan ini digunakan, misalnya untuk mendukung lingkungan tempat aplikasi disebarkan. Prosedur lazimnya adalah menyimpan semua pasangan kunci-nilai di bagian <appSettings> dari file Web.config:

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

Aplikasi membaca pengaturan ini menggunakan kumpulan ConfigurationManager.AppSettings dalam namespace System.Configuration:

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

ASP.NET dapat menyimpan data konfigurasi untuk aplikasi tersebut di file apa pun, lalu memuatnya sebagai bagian dari proses bootstrap middleware. File default yang digunakan dalam templat proyek adalah appsettings.json:

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

Pemuatan file ini ke instans IConfiguration dalam aplikasi Anda dilakukan di Startup.cs:

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

public IConfiguration Configuration { get; }

Aplikasi membaca dari Configuration untuk mendapatkan pengaturannya:

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

Ada ekstensi untuk metode ini agar prosesnya jadi makin andal. Misalnya, menggunakan Injeksi Dependensi (Dependency Injection/DI) untuk memuat layanan menggunakan nilai ini. Metode DI menyediakan serangkaian objek konfigurasi berjenis kuat.

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

Catatan

Untuk mengetahui seluk-beluk konfigurasi ASP.NET Core, baca Konfigurasi di ASP.NET Core.

Injeksi dependensi native

Target utama saat membuat aplikasi yang besar dan skalabel adalah pemasangan yang longgar atas komponen dan layanan. Injeksi Dependensi yang merupakan komponen native dari ASP.NET Core adalah teknik yang umum digunakan untuk mewujudkannya.

Di aplikasi ASP.NET, pengembang mengandalkan pustaka pihak ketiga untuk menerapkan Injeksi Dependensi. Salah satu pustaka tersebut adalah Unity, yang disediakan oleh Pola & Praktik Microsoft.

Satu contoh penyiapan Injeksi Dependensi dengan Unity adalah penerapan IDependencyResolver yang membungkus 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();
    }
}

Buat instans UnityContainer, daftarkan layanan, lalu tentukan resolver dependensi HttpConfiguration ke instans UnityResolver baru untuk kontainer Anda:

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

Masukkan IProductRepository jika perlu:

public class ProductsController : ApiController
{
    private IProductRepository _repository;

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

    // Other controller methods not shown.
}

Karena Injeksi Dependensi adalah bagian dari ASP.NET Core, Anda dapat menambahkan layanan dalam metode ConfigureServices dari Startup.cs:

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

Repositori dapat dimasukkan di mana pun, karena berlaku untuk Unity.

Catatan

Untuk mendapatkan informasi selengkapnya tentang injeksi dependensi, baca Injeksi dependensi.

Sajikan file statis

Salah satu bagian utama dari pengembangan web adalah kemampuan untuk melayani aset sisi klien yang statik. Contoh file statik paling umum adalah HTML, CSS, Javascript, dan gambar. File ini harus disimpan di lokasi resmi aplikasi (atau CDN) dan direferensikan agar file tersebut dapat dimuat oleh suatu permintaan. Proses ini telah berubah di ASP.NET Core.

Di ASP.NET, file statik disimpan di berbagai direktori dan direferensikan dalam tampilannya.

Di ASP.NET Core, file statik disimpan di "web root" (<content root>/wwwroot), kecuali konfigurasinya berbeda. File tersebut dimuat di alur permintaan dengan memanggil metode ekstensi UseStaticFiles dari Startup.Configure:

Catatan

Jika Anda menarget .NET Framework, instal paket NuGet Microsoft.AspNetCore.StaticFiles.

Misalnya, aset gambar dalam folder wwwroot/images dapat diakses oleh browser di lokasi, seperti http://<app>/images/<imageFileName>.

Catatan

Untuk mengetahui seluk-beluk penyajian file statik di ASP.NET Core, baca File statik.

cookie multinilai

ASP.NET Core tidak mendukung cookie multinilai. Buat satu cookie per nilai.

cookie autentikasi tidak dikompresi di ASP.NET Core

Demi keamanan, cookie autentikasi tidak dikompresi di ASP.NET Core. Saat menggunakan cookie autentikasi, pengembang harus meminimalkan jumlah informasi klaim yang ada. Cukup informasi klaim yang diperlukan saja.

Migrasi parsial atas aplikasi

Salah satu metode migrasi parsial atas aplikasi adalah dengan membuat sub-aplikasi IIS dan hanya memindahkan rute tertentu dari ASP.NET 4.x ke ASP.NET Core. Namun, struktur URL aplikasi harus dipertahankan. Misalnya, pertimbangkan struktur URL aplikasi dari file applicationHost.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>

Struktur direktori:

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

[BIND] dan Pemformat Input

Versi ASP.NET sebelumnya menggunakan atribut [Bind] demi mencegah serangan overposting. Ada perbedaan cara kerja Pemformat input di ASP.NET Core. Atribut [Bind] tidak lagi dirancang untuk mencegah overposting ketika digunakan bersama pemformat input untuk mengurai JSON atau XML. Atribut ini memengaruhi pengikatan model saat sumber datanya adalah data formulir yang dikirimkan dengan jenis konten x-www-form-urlencoded.

Untuk aplikasi yang mengirim informasi JSON ke pengontrol dan menggunakan Pemformat Input JSON untuk mengurai data, sebaiknya ganti atribut [Bind] dengan model tampilan yang sesuai dengan properti yang ditentukan oleh atribut [Bind].

Sumber daya tambahan