Cara memutakhirkan proyek yang ada dari ASP.NET MVC ke ASP.NET Core. Panduan praktis

Posting ini lahir dari pengalaman kami memigrasikan proyek yang ada dari ASP.NET MVC ke ASP.NET Core. Kami mencoba menyatukan seluruh proses migrasi dalam bentuk terstruktur dan menggambarkan berbagai hambatan sehingga pengembang dapat terus bergantung pada materi ini dan mengikuti peta jalan dalam menyelesaikan masalah tersebut.

Beberapa kata tentang proyek kami. Kami adalah platform eCommerce open-source di ASP.NET, yang pada saat transfer sudah ada dengan sukses selama 9 tahun. Kami melakukan migrasi 2 tahun yang lalu - tetapi tangan kami datang untuk menulis tentang hal itu sekarang. Pada saat itu, kami adalah salah satu proyek besar pertama yang memutuskan langkah seperti itu.

Mengapa beralih ke ASP.NET Core?


Sebelum melanjutkan dengan langkah-langkah untuk bermigrasi dari ASP.NET MVC ke ASP.NET Core, beberapa kata tentang manfaat platform ini.



Manfaat dari ASP.NET Core
Jadi, ASP.NET Core sudah merupakan kerangka kerja yang cukup terkenal dan dikembangkan, yang telah mengalami beberapa pembaruan besar, yang berarti bahwa saat ini cukup stabil, maju secara teknologi dan tahan terhadap serangan XSRF / CSRF.

Cross - platform adalah salah satu keunggulan yang memungkinkannya untuk mendapatkan popularitas yang semakin banyak. Mulai sekarang, aplikasi web Anda dapat berjalan di lingkungan Windows dan Unix.

Modularitas - ASP.NET Core hadir sepenuhnya dalam bentuk paket NuGet, ini memungkinkan Anda untuk mengoptimalkan aplikasi, termasuk paket yang diperlukan yang dipilih. Ini meningkatkan kinerja solusi dan mengurangi waktu yang diperlukan untuk memutakhirkan bagian-bagian individual. Ini adalah fitur penting kedua yang memungkinkan pengembang untuk lebih fleksibel mengintegrasikan fitur-fitur baru ke dalam solusi mereka.

Kinerja adalah langkah lain untuk membangun aplikasi berkinerja tinggi, ASP.NET Core memproses 2300% lebih banyak permintaan per detik dari ASP.NET 4.6, dan 800% lebih banyak permintaan per detik daripada node.js. Anda dapat memeriksa sendiri tes kinerja terperinci di sini atau di sini .



Middleware adalah pipa modular ringan kinerja tinggi baru untuk permintaan dalam aplikasi. Setiap bagian middleware memproses permintaan HTTP, dan kemudian memutuskan untuk mengembalikan hasilnya, atau melewati bagian middleware berikutnya. Pendekatan ini memberikan pengembang kontrol penuh atas pipa HTTP dan berkontribusi pada pengembangan modul sederhana untuk aplikasi, yang penting untuk proyek open source yang berkembang.

ASP.NET Core MVC menyediakan fitur yang menyederhanakan pengembangan web. NopCommerce telah menggunakan fitur seperti template Model-View-Controller, sintaks Razor, pengikatan dan validasi model, tetapi alat baru muncul:

  • Beri Tag pada Pembantu. Ini adalah kode sisi server untuk berkontribusi pada pembuatan dan rendering elemen HTML dalam file Razor.
  • Lihat komponen. Ini adalah alat baru, mirip dengan tampilan sebagian, tetapi jauh lebih kuat. nopCommerce menggunakan komponen tampilan ketika menggunakan kembali logika rendering diperlukan dan ketika tugas terlalu kompleks untuk tampilan parsial.
  • Tampilan DI. Meskipun sebagian besar data yang ditampilkan dalam pandangan dilewatkan dari controller, nopCommerce memiliki pandangan di mana injeksi ketergantungan lebih nyaman.

Tentu saja, ASP.NET Core memiliki lebih banyak fitur, tetapi kami baru saja memeriksa yang paling menarik.

Sekarang mari kita bicara tentang apa yang harus Anda pertimbangkan ketika porting aplikasi Anda ke platform baru.

Migrasi


Teks akan berisi sejumlah besar tautan ke dokumentasi resmi ASP.NET Core untuk membantu mendapatkan informasi lebih rinci tentang topik tersebut. Terutama relevan untuk pengembang yang dihadapkan dengan tugas serupa untuk pertama kalinya.

Langkah 1. Persiapan alat


Hal pertama yang perlu Anda lakukan adalah meningkatkan Visual Studio 2017 ke versi 15.3 atau lebih tinggi. Dan instal versi terbaru .NET Core SDK.

Sebelum memulai migrasi, Anda disarankan untuk menggunakan alat analisis portabilitas .NET .Net Portability Analyzer . Ini adalah titik awal yang baik untuk memahami betapa sulitnya transisi dari satu platform ke platform lainnya. Tapi, tentu saja, alat ini tidak menyelesaikan semua masalah, dan dalam prosesnya akan ada banyak jebakan. Selanjutnya, tahapan utama yang perlu dilewati akan dijelaskan, dan solusi yang digunakan dalam proyek kami akan ditampilkan.

Hal pertama yang Anda butuhkan adalah memperbarui tautan ke perpustakaan yang digunakan dalam proyek yang akan mendukung .NET Standard.

Langkah 2. Analisis kompatibilitas paket NuGet untuk mendukung Standar Net


Jika Anda menggunakan paket NuGet dalam proyek Anda, Anda perlu memeriksa apakah mereka kompatibel dengan .NET Core. Salah satu cara untuk melakukan ini adalah dengan menggunakan alat NuGetPackageExplorer .

Langkah 3. .NET Core menggunakan format file csproj yang baru


Penting untuk menggunakan pendekatan baru untuk menambahkan tautan pihak ketiga yang diperkenalkan di .NET Core: ketika perpustakaan kelas baru ditambahkan ke solusi, Anda harus membuka file proyek utama dan mengganti isinya dengan yang berikut:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.6" /> ... </ItemGroup> ... </Project> 

Tautan dari perpustakaan yang terhubung akan diunduh secara otomatis. Informasi lebih lanjut tentang pemetaan antara properti project.json dan CSPROJ dapat ditemukan di dokumentasi resmi di sini dan di sini .

Langkah 4. Memperbarui namespace


Anda harus menghapus semua penggunaan System.Web dan menggantinya dengan Microsoft.AspNetCore.

Langkah 5. Anda harus mengonfigurasi file Startup.cs. alih-alih menggunakan global.asax


ASP.NET Core memiliki mekanisme baru untuk memuat aplikasi. Titik masuk ke aplikasi menjadi Startup , dan ketergantungan pada file Global.asax menghilang. Startup mendaftarkan suite middleware dalam aplikasi. Startup harus menyertakan metode Configure . Di Configure tambahkan middleware yang diperlukan ke saluran pipa.

Masalah startup.cs

  1. Mengkonfigurasi middleware untuk permintaan MVC dan WebAPI
  2. Pengaturan konfigurasi untuk:


 //add basic MVC feature var mvcBuilder = services.AddMvc(); //add custom model binder provider (to the top of the provider list) mvcBuilder.AddMvcOptions(options => options.ModelBinderProviders.Insert(0, new NopModelBinderProvider())); /// <summary> /// Represents model binder provider for the creating NopModelBinder /// </summary> public class NopModelBinderProvider : IModelBinderProvider { /// <summary> /// Creates a nop model binder based on passed context /// </summary> /// <param name="context">Model binder provider context</param> /// <returns>Model binder</returns> public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); var modelType = context.Metadata.ModelType; if (!typeof(BaseNopModel).IsAssignableFrom(modelType)) return null; //use NopModelBinder as a ComplexTypeModelBinder for BaseNopModel if (context.Metadata.IsComplexType && !context.Metadata.IsCollectionType) { //create binders for all model properties var propertyBinders = context.Metadata.Properties .ToDictionary(modelProperty => modelProperty, modelProperty => context.CreateBinder(modelProperty)); return new NopModelBinder(propertyBinders, EngineContext.Current.Resolve<ILoggerFactory>()); } //or return null to further search for a suitable binder return null; } } 



 app.UseMvc(routes => { routes.MapRoute("areaRoute", "{area:exists}/{controller=Admin}/{action=Index}/{id?}"); routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); 

Pada saat yang sama, folder dengan Area nama, di dalam mana folder Admin berada, harus ditempatkan di root aplikasi. Sekarang, atribut [Area("Admin")] [Route("admin")] akan digunakan untuk menghubungkan controller dengan area ini.
Tetap hanya untuk membuat tampilan untuk semua tindakan yang dijelaskan dalam controller.


 [Area("Admin")] [Route("admin")] public class AdminController : Controller { public IActionResult Index() { return View(); } } 

Validasi

Sekarang Anda tidak perlu meneruskan IFormCollection ke pengendali, karena dalam kasus ini validasi server asp.net dinonaktifkan - MVC sedang menekan validasi lebih lanjut jika IFormCollection ditemukan bukan nol. Solusi untuk masalah ini dapat menambahkan properti ini ke model, ini akan mencegah kita melewati langsung ke metode pengontrol. Aturan ini hanya valid jika ada model, tetapi jika tidak ada model, maka tidak akan ada validasi.

Properti anak tidak lagi divalidasi secara otomatis. Itu harus ditentukan secara manual.

Langkah 6. Mentransfer penangan HTTP dan modul HTTP ke Middleware


Penangan HTTP dan modul HTTP pada dasarnya sangat mirip dengan konsep Middleware di ASP.NET Core , tetapi tidak seperti modul, urutan middleware didasarkan pada urutan di mana mereka dimasukkan ke dalam pipa permintaan. Urutan modul, sebagian besar, didasarkan pada peristiwa siklus hidup aplikasi . Urutan middleware untuk jawaban adalah kebalikan dari urutan permintaan, dan urutan modul untuk permintaan dan jawaban adalah sama. Berdasarkan ini, Anda dapat melanjutkan dengan peningkatan.

Jadi, apa yang masih harus diperbarui:

  • Migrasi modul untuk Middleware (AuthenticationMiddleware, CultureMiddleware, dll.)
  • Penangan ke Middleware
  • Menggunakan Middleware Baru

Otentikasi dalam proyek kami tidak menggunakan sistem kredensial bawaan, untuk tujuan ini, middleware AuthenticationMiddleware digunakan, dikembangkan sesuai dengan struktur Core ASP.NET baru.

 public class AuthenticationMiddleware { private readonly RequestDelegate _next; public AuthenticationMiddleware(IAuthenticationSchemeProvider schemes, RequestDelegate next) { Schemes = schemes ?? throw new ArgumentNullException(nameof(schemes)); _next = next ?? throw new ArgumentNullException(nameof(next)); } public IAuthenticationSchemeProvider Schemes { get; set; } public async Task Invoke(HttpContext context) { context.Features.Set<IAuthenticationFeature>(new AuthenticationFeature { OriginalPath = context.Request.Path, OriginalPathBase = context.Request.PathBase }); var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>(); foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync()) { try { if (await handlers.GetHandlerAsync(context, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync()) return; } catch { // ignored } } var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync(); if (defaultAuthenticate != null) { var result = await context.AuthenticateAsync(defaultAuthenticate.Name); if (result?.Principal != null) { context.User = result.Principal; } } await _next(context); } } 

ASP.NET menyediakan banyak middleware tertanam yang dapat Anda gunakan dalam aplikasi Anda, tetapi perhatikan bahwa pengembang memiliki kemampuan untuk membuat middleware sendiri dan menambahkannya ke pipa permintaan HTTP. Untuk menyederhanakan mekanisme ini, kami menambahkan antarmuka khusus, dan sekarang cukup untuk membuat kelas yang mengimplementasikannya.

 public interface INopStartup { /// <summary> /// Add and configure any of the middleware /// </summary> /// <param name="services">Collection of service descriptors</param> /// <param name="configuration">Configuration of the application</param> void ConfigureServices(IServiceCollection services, IConfiguration configuration); /// <summary> /// Configure the using of added middleware /// </summary> /// <param name="application">Builder for configuring an application's request pipeline</param> void Configure(IApplicationBuilder application); /// <summary> /// Gets order of this startup configuration implementation /// </summary> int Order { get; } } 

Di sini Anda dapat menambah dan mengkonfigurasi middleware Anda:

 /// <summary> /// Represents object for the configuring authentication middleware on application startup /// </summary> public class AuthenticationStartup : INopStartup { /// <summary> /// Add and configure any of the middleware /// </summary> /// <param name="services">Collection of service descriptors</param> /// <param name="configuration">Configuration of the application</param> public void ConfigureServices(IServiceCollection services, IConfiguration configuration) { //add data protection services.AddNopDataProtection(); //add authentication services.AddNopAuthentication(); } /// <summary> /// Configure the using of added middleware /// </summary> /// <param name="application">Builder for configuring an application's request pipeline</param> public void Configure(IApplicationBuilder application) { //configure authentication application.UseNopAuthentication(); } /// <summary> /// Gets order of this startup configuration implementation /// </summary> public int Order => 500; //authentication should be loaded before MVC } 

Langkah 7. Menggunakan DI Terintegrasi


Ketergantungan injeksi adalah salah satu fitur utama dalam proses desain aplikasi di ASP.NET Core. Hal ini memungkinkan Anda untuk membuat aplikasi yang digabungkan secara longgar yang lebih dapat diuji, modular dan, akibatnya, dapat dipelihara. Ini dimungkinkan dengan mengikuti prinsip inversi ketergantungan. Untuk menginstal dependensi, wadah IoC (Inversion of Control) digunakan. Dalam ASP.NET Core, wadah seperti itu diwakili oleh antarmuka IServiceProvider. Layanan diinstal dalam aplikasi dalam metode Startup.ConfigureServices() .

Setiap layanan terdaftar dapat dikonfigurasi dengan tiga cakupan:

  • sementara
  • tercakup
  • singleton

 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddSingleton<Isingleton,MySingleton>(); 

Langkah 8. Menggunakan Kerangka Kompatibilitas Proyek WebAPI (Shim)


Untuk menyederhanakan migrasi implementasi API Web yang ada, disarankan untuk menggunakan paket Microsoft.AspNetCore.Mvc.WebApiCompatShim NuGet. Fungsi-fungsi yang kompatibel berikut ini didukung:

  • Menambahkan Tipe ApiController
  • Mengaktifkan pengikatan model gaya API web
  • Memperpanjang model mengikat sehingga tindakan pengontrol dapat menerima parameter tipe HttpRequestMessage.
  • Menambahkan pemformat pesan yang memungkinkan tindakan untuk mengembalikan hasil tipe HttpResponseMessage

 services.AddMvc().AddWebApiConventions(); routes.MapWebApiRoute(name: "DefaultApi", template: "api/{controller}/{id?}" ); 

Langkah 9. Transfer Konfigurasi Aplikasi


Sebelumnya, beberapa pengaturan disimpan dalam file web.config. Kami sekarang mengambil pendekatan baru berdasarkan pasangan kunci-nilai yang dibuat oleh penyedia konfigurasi . Ini adalah mekanisme yang disarankan dalam ASP.NET Core, dan kami menggunakan file appsettings.json.

Anda juga dapat menggunakan System.Configuration.ConfigurationManager paket NuGet jika karena alasan tertentu Anda ingin terus menggunakan * .config. Dalam hal ini, Anda harus meninggalkan kemampuan untuk menjalankan aplikasi pada platform Unix dan menjalankannya hanya di bawah IIS.

Jika Anda ingin menggunakan penyedia konfigurasi Azure Key Vault , Anda harus merujuk ke Migrasi Konten ke konten Valut Azure Key . Dalam proyek kami, ini bukan tugas.

Langkah 10. Mentransfer konten statis ke wwwroot


Untuk menyajikan konten statis, Anda harus memberi tahu host web akar dari isi direktori saat ini. Standarnya adalah wwwroot. Anda dapat menyesuaikan direktori Anda untuk menyimpan file statis dengan mengatur middleware.



Langkah 11. Porting EntityFramework ke EF Core


Jika proyek menggunakan beberapa fitur spesifik dari Entity Framework 6 yang tidak didukung di EF Core , maka masuk akal untuk menjalankan aplikasi pada NET Framework . Namun, dalam hal ini, Anda harus mengorbankan multiplatform. Aplikasi hanya akan berfungsi di Windows dan di bawah IIS.

Mari kita lihat perubahan-perubahan utama yang harus diperhitungkan:

  • System.Data.Entity namespace digantikan oleh Microsoft.EntityFrameworkCore
  • Tanda tangan konstruktor DbContext telah diubah. Sekarang Anda perlu menyuntikkan DbContextOptions
  • Metode HasDatabaseGeneratedOption (DatabaseGeneratedOption.None) digantikan oleh ValueGeneratedNever ()
  • Metode WillCascadeOnDelete (false) digantikan oleh OnDelete (DeleteBehavior.Restrict)
  • Metode OnModelCreating (DbModelBuilder modelBuilder) digantikan oleh OnModelCreating (ModelBuilder modelBuilder)
  • Metode HasOptional tidak lagi tersedia
  • konfigurasi objek diubah, sekarang Anda perlu menggunakan OnModelCreating, karena Konfigurasi EntityType tidak lagi tersedia
  • Atribut ComplexType tidak lagi tersedia
  • Penggantian antarmuka IDbSet dengan DbSet
  • ComplexType - dukungan tipe kompleks muncul di EF Core 2 dengan tipe Entitas yang Dimiliki ( https://docs.microsoft.com/en-us/ef/core/modeling/ owned-entities), dan tabel tanpa Kunci Utama dengan QueryType di EF Core 2.1 ( https://docs.microsoft.com/en-us/ef/core/modeling/query-types )
  • kunci asing di EF Core menghasilkan properti bayangan menggunakan pola ID [Entity], tidak seperti EF6, yang menggunakan pola [Entity] _Id. Oleh karena itu, pertama-tama tambahkan kunci asing sebagai properti biasa ke entitas.
  • Untuk mendukung DI untuk DbContext, konfigurasikan DbContex Anda di ConfigureServices

 /// <summary> /// Register base object context /// </summary> /// <param name="services">Collection of service descriptors</param> public static void AddNopObjectContext(this IServiceCollection services) { services.AddDbContextPool<NopObjectContext>(optionsBuilder => { optionsBuilder.UseSqlServerWithLazyLoading(services); }); } /// <summary> /// SQL Server specific extension method for Microsoft.EntityFrameworkCore.DbContextOptionsBuilder /// </summary> /// <param name="optionsBuilder">Database context options builder</param> /// <param name="services">Collection of service descriptors</param> public static void UseSqlServerWithLazyLoading(this DbContextOptionsBuilder optionsBuilder, IServiceCollection services) { var nopConfig = services.BuildServiceProvider().GetRequiredService<NopConfig>(); var dataSettings = DataSettingsManager.LoadSettings(); if (!dataSettings?.IsValid ?? true) return; var dbContextOptionsBuilder = optionsBuilder.UseLazyLoadingProxies(); if (nopConfig.UseRowNumberForPaging) dbContextOptionsBuilder.UseSqlServer(dataSettings.DataConnectionString, option => option.UseRowNumberForPaging()); else dbContextOptionsBuilder.UseSqlServer(dataSettings.DataConnectionString); } 

Gunakan alat SQL Compare untuk memverifikasi bahwa EF Core menghasilkan skema basis data yang sama dengan Entity Framework selama migrasi .

Langkah 12. Menghapus semua referensi HttpContext, mengganti kelas yang sudah usang, dan mengubah namespace


Selama migrasi proyek Anda, Anda akan menemukan bahwa sejumlah besar kelas telah diubah namanya atau dipindahkan, dan sekarang Anda perlu menyesuaikan semuanya dengan persyaratan baru. Berikut adalah daftar transisi utama yang mungkin Anda temui:

  • HttpPostedFileBase -> IFormFile
  • Akses untuk mengakses HttpContext sekarang melalui IHttpContextAccessor
  • HtmlHelper -> IHtmlHelper
  • ActionResult -> IActionResult
  • HttpUtility -> WebUtility
  • Alih-alih HttpSessionStateBase - ISession, dapat diakses dari HttpContext.Session. dari Microsoft.AspNetCore.Http
  • Request.Cookies mengembalikan IRequestCookieCollection: IEnumerable <KeyValuePair <string, string >>, jadi alih-alih HttpCookie, KeyValuePair <string, string> dari Microsoft.AspNetCore.Http

Penggantian ruang nama:

  • SelectList -> Microsoft.AspNetCore.Mvc.Rendering
  • UrlHelper -> WebUtitlity
  • MimeMapping -> FileExtensionContentTypeProvider
  • MvcHtmlString -> IHtmlString dan HtmlString
  • ModelState, ModelStateDictionary, ModelError -> Microsoft.AspNetCore.Mvc.ModelBinding
  • FormCollection -> IFormCollection
  • Request.Url.Scheme -> this.Url.ActionContext.HttpContext.Request.Scheme

Lainnya:

  • MvcHtmlString.IsNullOrEmpty (IHtmlString) -> String.IsNullOrEmpty (variabel.ToHtmlString ())
  • [ValidateInput (false)] - umumnya tidak lebih dan tidak diperlukan
  • HttpUnauthorizedResult -> UnauthorizedResult
  • [AllowHtml] - tidak ada lagi arahan dan itu tidak diperlukan
  • Metode TagBuilder.SetInnerText diganti - sekarang ini adalah InnerHtml.AppendHtml
  • JsonRequestBehavior.AllowDapat ketika mengembalikan Json tidak lagi diperlukan
  • HttpUtility.JavaScriptStringEncode. -> JavaScriptEncoder.Default.Encode
  • Permintaan.RawUrl. Hal ini diperlukan untuk menghubungkan secara terpisah Request.Path + Request.QueryString
  • AllowHtmlAttribute - tidak ada lagi kelas
  • XmlDownloadResult - sekarang Anda dapat menggunakan hanya mengembalikan File (Encoding.UTF8.GetBytes (xml), "application / xml", "filename.xml");
  • [ValidateInput (false)] - tidak ada lagi arahan dan tidak diperlukan

Langkah 13. Memperbarui Otentikasi dan Otorisasi


Saya sudah menulis di atas bahwa dalam proyek kami otentikasi tidak diimplementasikan menggunakan sistem identitas bawaan, tetapi dikeluarkan dalam lapisan middleware terpisah. Namun, ASP.NET Core memiliki mekanisme sendiri untuk memberikan kredensial. Rincian lebih lanjut dapat ditemukan di dokumentasi di sini .

Adapun perlindungan data - kami tidak lagi menggunakan MachineKey . Sebagai gantinya, kami menggunakan fitur perlindungan data bawaan. Secara default, kunci dibuat saat aplikasi dimulai. Gudang data dapat:

  • Sistem file - keystore berbasis sistem file
  • Azure Storage - kunci perlindungan data di Azure Blob Storage
  • Redis - kunci perlindungan data dalam cache Redis
  • Registri - harus digunakan jika aplikasi tidak memiliki akses ke sistem file
  • EF Core - kunci disimpan dalam basis data

Jika mekanisme bawaan tidak cocok, Anda bisa menentukan mekanisme penyimpanan kunci Anda sendiri dengan menyediakan tempat penyimpanan IXml kustom.

Langkah 14. Memperbarui JS / CSS


Cara bekerja dengan sumber daya statis telah berubah: sekarang semuanya harus disimpan dalam folder root dari proyek wwwroot , kecuali, tentu saja, pengaturan lain ditentukan.

Saat menggunakan blok javascript bawaan, Anda disarankan untuk memindahkannya ke akhir halaman. Cukup gunakan atribut asp-location = "Footer" untuk tag Anda. Aturan yang sama berlaku untuk file js.

Gunakan ekstensi BundlerMinifier sebagai pengganti System.Web.Optimization - ini akan memungkinkan Anda untuk mengikat dan meminimalkan JavaScript dan CSS saat membangun proyek. Tautan ke dokumentasi.

Langkah 15. Memigrasi Tampilan


Tindakan Anak tidak lagi digunakan. Sebaliknya, ASP.NET Core menawarkan alat yang kuat baru - ViewComponents , yang disebut tidak sinkron.

Cara mendapatkan string dari ViewComponent:

 /// <summary> /// Render component to string /// </summary> /// <param name="componentName">Component name</param> /// <param name="arguments">Arguments</param> /// <returns>Result</returns> protected virtual string RenderViewComponentToString(string componentName, object arguments = null) { if (string.IsNullOrEmpty(componentName)) throw new ArgumentNullException(nameof(componentName)); var actionContextAccessor = HttpContext.RequestServices.GetService(typeof(IActionContextAccessor)) as IActionContextAccessor; if (actionContextAccessor == null) throw new Exception("IActionContextAccessor cannot be resolved"); var context = actionContextAccessor.ActionContext; var viewComponentResult = ViewComponent(componentName, arguments); var viewData = ViewData; if (viewData == null) { throw new NotImplementedException(); } var tempData = TempData; if (tempData == null) { throw new NotImplementedException(); } using (var writer = new StringWriter()) { var viewContext = new ViewContext( context, NullView.Instance, viewData, tempData, writer, new HtmlHelperOptions()); // IViewComponentHelper is stateful, we want to make sure to retrieve it every time we need it. var viewComponentHelper = context.HttpContext.RequestServices.GetRequiredService<IViewComponentHelper>(); (viewComponentHelper as IViewContextAware)?.Contextualize(viewContext); var result = viewComponentResult.ViewComponentType == null ? viewComponentHelper.InvokeAsync(viewComponentResult.ViewComponentName, viewComponentResult.Arguments): viewComponentHelper.InvokeAsync(viewComponentResult.ViewComponentType, viewComponentResult.Arguments); result.Result.WriteTo(writer, HtmlEncoder.Default); return writer.ToString(); } } 

Tidak perlu menggunakan HtmlHelper lagi - ASP.NET Core memiliki banyak fungsi tag pembantu ( Tag Helpers ) bawaan . Ketika aplikasi sedang berjalan, mereka diproses oleh mesin Razor di sisi server dan akhirnya dikonversi ke elemen html standar. Ini sangat menyederhanakan pengembangan aplikasi. Dan, tentu saja, Anda dapat menerapkan tag-help Anda sendiri.

Kami mulai menggunakan injeksi dependensi dalam tampilan alih-alih mengizinkan pengaturan dan layanan menggunakan EngineContext .

Jadi, poin utama tentang migrasi tampilan:

  • Konversi Views/web.config Views/_ViewImports.cshtml - digunakan untuk mengimpor ruang nama dan Views/web.config Views/_ViewImports.cshtml dependensi. File ini tidak mendukung fungsi Razor lainnya, seperti definisi fungsi dan bagian.
  • Konversikan namespaces.add ke @using
  • Transfer pengaturan apa pun ke konfigurasi aplikasi utama
  • Scripts.Render dan Styles.Render tidak ada. Ganti libman atau BundlerMinifier tautan ke keluaran

Kesimpulannya


Kami telah melihat dari pengalaman kami bahwa proses migrasi aplikasi web besar adalah tugas yang sangat memakan waktu yang hampir tidak dapat dilakukan tanpa jebakan. Kami berencana untuk beralih ke kerangka kerja baru segera setelah versi stabil pertama dirilis, tetapi kami tidak dapat menyelesaikannya segera: ada beberapa fungsi penting yang pada saat itu belum ditransfer ke .NET Core, khususnya, terkait dengan EntityFramework. Oleh karena itu, kami harus terlebih dahulu merilis rilis berikutnya menggunakan pendekatan campuran - arsitektur .NET Core dengan dependensi .NET Framework.

Kami dapat sepenuhnya menyesuaikan proyek setelah rilis. NET Core 2.1, pada saat itu solusi stabil sudah bekerja pada arsitektur baru - yang tersisa hanyalah mengganti beberapa paket dan menulis ulang pekerjaan dengan EF Core. Dengan demikian, migrasi lengkap ke kerangka kerja baru membutuhkan beberapa bulan kerja.

Anda dapat mempelajari lebih lanjut tentang proyek kami dari repositori kami di GitHub .

Source: https://habr.com/ru/post/id472738/


All Articles